桂电c语言实验循环,桂电-数学与计算科学学院-《数据结构实验-宁黎华编》(实验三)...

本文介绍了一个使用栈结构检查括号匹配性的程序设计案例,详细解释了如何利用栈的特性实现括号配对检查,并提供了完整的C语言代码示例。此外,还探讨了栈在数制转换中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实验三:栈的基本运算

1、实验目的

(1)掌握栈的各种存储结构及基本运算的实现。

(2)掌握堆栈后进先出的运算原则在解决实际问题中的应用。

(3)复习c语言中相关语句及函数的用法。

2、实验要求

(1)熟练掌握栈的存储结构及其基本操作。

(2)理解所给出的算法,掌握栈在实际中的应用。

(3)将上机程序调试通过,并能独立完成一至两个拓展题目。

3、实验内容

括号配对检查。试设计一个程序对任意输入的语句或数学表达式,判断其括号是否匹配。若匹配,则返回1,否则返回0。调试程序并对相应的输出作出分析;修改输入数据,预期输出并验证输出的结果。加深对算法的理解。

4、实验方法

首先建立一个栈结构,且初始化栈为空。然后由键盘上随即输入一个带括号的语句或带括号的数学表达式,同时将它们保存在一个字符型数组exps[]中。扫描表达式exps,当遇到“(”、“[”、“{”时,将其入栈。遇到“)”、“]”、“}”时,判断栈顶是否有相匹配的括号。若没有,则退出扫描过程,返回0,否则直到exps扫描完毕为止。若top为0,则返回1。

5、验证程序

#include "stdio.h"

#define MAXSIZE 100

#define TRUE 1

#define FALSE 0

#define NULL 0

typedef int datatype;

typedef struct /*顺序栈的结构体类型定义*/

{datatype stack[MAXSIZE];

int top;

}seqstack;

void setnull(seqstack *s) //置空栈-由于c语言的数组下标是从0开始的,所以置

{s->top=-1;} //空栈操作时将栈顶指针放在下标为0之前,即-1处。

int empty(seqstack *s) /*判断当前栈是否为空栈*/

{if(s->top<0)

return TRUE;

else

return FALSE;

}

int push(seqstack *s,datatype x) /*把元素x压入栈s中*/

{if(s->top>=MAXSIZE-1)

{printf("stack overflow!

"); /*发生上溢*/

return FALSE;

}

else

{s->stack[++s->top]=x; /*栈顶指针上移,数据元素入栈*/

return TRUE;

}

}

datatype pop(seqstack *s) /*弹出当前栈s的栈顶元素*/

{if(s->top<0)

{printf("stack empty!

"); /*栈空,返回空值*/

return NULL;

}

else

{s->top--;

return(s->stack[s->top+1]);

}//由于return语句的特点,必须先使top减1,然后再执行return语句。而此

} //时栈顶元素的表示应该为s->top+1.

int judge(seqstack *s) //括号匹配检查算法。--遇到"("、"["、"{"时,将其压入栈s中。

{

datatype symb,ch;

push(s,'#');

symb=getchar();//从键盘接受字符

while(symb!='#')

{

switch(symb)

{

case '(':

case '[':

case '{': push(s,symb);break;

case ')':

ch=pop(s);

if(ch!='(') return FALSE;

break;

case ']':

ch=pop(s);

if(ch!='[') return FALSE;

break;

case '}':

ch=pop(s);

if(ch!='{') return FALSE;

break;

default:;

}

symb=getchar();

}

if(pop(s)=='#') return TRUE;

else return FALSE;

}

main()

{

seqstack q;

setnull(&q);

printf("please input an express end with symbol '#':

");

if(judge(&q)) printf("yes

"); //括号匹配,则输出yes

else printf("no

"); //括号不匹配,则输出no

}

验证程序结果如下图:

3f288ee285423cc6e29fa526842ca321.png

3f288ee285423cc6e29fa526842ca321.png

6、预习思考题

调试好上述程序后,试着完成以下拓展内容:

(1)假定表达式不是通过getchar()函数一个个传送的,而是存放在一个字符数组A[n]中,程序需要做哪些改变?

(2)在judge()函数中,如果不用switch()函数,你会怎么处理?

思考一:解题思路是用数组储存字符,并用数组传递字符。在主函数里面定义一个字符,用一个for循环向数组输入字符,以#结束。在传递数据的时候,传递栈和数组即可,在子函数中用while(B[i]!=’#’)进行读取字符,进而取代getchar()函数。

int judge(seqstack *s,char B[]) //括号匹配检查算法。--遇到"("、"["、"{"时,将其压入栈s中。

{

datatype symb,ch;

int i=0;

push(s,'#');

while(B[i]!='#')

{

symb=B[i];

switch(symb)

{

case '(':

case '[':

case '{': push(s,symb);break;

case ')':

ch=pop(s);

if(ch!='(') return FALSE;

break;

case ']':

ch=pop(s);

if(ch!='[') return FALSE;

break;

case '}':

ch=pop(s);

if(ch!='{') return FALSE;

break;

default:;

}

i++;

}

if(pop(s)=='#') return TRUE;

else return FALSE;

}

main()//主函数

{

char A[MAXSIZE];

int i=0;

seqstack q;

setnull(&q);

printf("please input an express end with symbol '#':

");

for(i=0;i思考二:解题思路可以用if······else······if····嵌套实现,此时要注意,要把之前的break删掉,否则会提前退出。

int judge(seqstack *s) //括号匹配检查算法。--遇到"("、"["、"{"时,将其压入栈s中。

{

datatype symb,ch;

push(s,'#');

symb=getchar();//从键盘接受字符

while(symb!='#')

{

if(symb=='('||symb=='['||symb=='{')

{

push(s,symb);

}

else if(symb==')')

{

ch=pop(s);

if(ch!='(') return FALSE;

}

else if(symb==']')

{ ch=pop(s);

if(ch!='[') return FALSE;

}

else if(symb=='}')

{ ch=pop(s);

if(ch!='{') return FALSE;

}

symb=getchar();

}

if(pop(s)=='#') return TRUE;

else return FALSE;

}

main()

{

seqstack q;

setnull(&q);

printf("please input an express end with symbol '#':

");

if(judge(&q)) printf("yes

"); //括号匹配,则输出yes

else printf("no

"); //括号不匹配,则输出no

}

将上述代码直接和之前的源代码替换即可。

7、分析讨论题:

数制转换问题是栈应用的一个典型实例。将十进制数转换成其它进制的数有一种简单的方法:例:十进制转换成八进制:(66)10=(102)8

66/8=8 余 2

8/8=1 余 0

1/8=0 余 1

结果为余数的逆序:102 。如果用栈的算法来实现,怎样实现?其基本原理是什么?

解题思路:根据进制转化的算法,取余之后倒序输出。同时栈也是先进后出的性质,可以用栈来依次储存余数,最后输出栈元素,即可转化进制。

算法实现:用x表示需要转化的数,用N表示转化的进制。

void trans(seqstack *s,int x,int N)

{

while(x!=0)

{

push(s,x%N);

x=x/N;

}

while(s->top!=-1)

printf("%d",pop(s));

}

main()

{

int a,b;

seqstack q;

setnull(&q);

printf("请输入需要转换的数和与转换进制类型:

");

scanf("%d%d",&a,&b);

printf("输出结果:

");

trans(&q,a,b);

printf("

");

}

上述代码可以转换成任意进制。

3f288ee285423cc6e29fa526842ca321.png

3f288ee285423cc6e29fa526842ca321.png

3f288ee285423cc6e29fa526842ca321.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值