表达式计算实验报告.docx
《表达式计算实验报告.docx》由会员分享,可在线阅读,更多相关《表达式计算实验报告.docx(13页珍藏版)》请在冰豆网上搜索。
![表达式计算实验报告.docx](https://file1.bdocx.com/fileroot1/2023-6/22/8a4575fb-87de-45ce-b857-880d23d6ae2c/8a4575fb-87de-45ce-b857-880d23d6ae2c1.gif)
表达式计算实验报告
数据结构(双语)
——项目文档报告
用两种方式实现表达式自动计算
专业:
计算机科学与技术
班级:
11接计1
指导教师:
苏亚光
姓名:
邢长璇
学号:
0
一、设计思想
中缀变后缀表达式的基本思路:
使用一个栈和一个数组(栈是运算符栈,数组是用来存放后缀表达式)用于表达式的转换
(1)定义一个字符数组,并输入一个中缀表达式。
然后从中缀表达式中从左往右依次读入各个字符。
(2)如果是数字字符,则直接将它们写入后缀表达式中即队列中。
(3)如果遇到的是开括号“(”,则将它们压入一个操作符栈(不需要与栈顶操作符相比较),它表明一个新的计算层次的开始,在遇到和它匹配的闭括号“)”时,将栈中的元素弹出来并放入后缀表达式中,直到栈顶元素为“(”时,将栈顶元素“(”弹出(不需要加入后缀表达式),表明这一层括号内的操作处理完毕。
(4)如果遇到的是操作符,则将该操作符和操作符栈顶元素比较:
当所遇到的操作符的优先级小于或等于栈顶元素的优先级时,则取出栈顶元素放入后缀表达式,并弹出该栈顶元素,反复执行直到操作符的优先级大于栈顶元素的优先级的时则将它压入栈中。
(5)重复上述步骤直到缀表达式的结束符标记“#“,弹出栈中所有元素并放入后缀表达,转换结束。
中缀变前缀表达式的基本思路:
使用一个栈和一个数组(栈是运算符栈,数组是用来存放后缀表达式)用于表达式的转换
(1)定义一个字符数组,并输入一个中缀表达式。
然后从中缀表达式中从右往左依次读入各个字符。
(2)如果是数字字符,则直接将它们写入后缀表达式中即队列中。
(3)如果遇到的是开括号“)”,则将它们压入一个操作符栈(不需要与栈顶操作符相比较),它表明一个新的计算层次的开始,在遇到和它匹配的闭括号“(”时,将栈中的元素弹出来并放入前缀表达式中,直到栈顶元素为“)”时,将栈顶元素“)”弹出(不需要加入后缀表达式),表明这一层括号内的操作处理完毕
(4)如果遇到的是操作符,则将该操作符和操作符栈顶元素比较:
当所遇到的操作符的优先级小于栈顶元素的优先级时,则取出栈顶元素放入后缀表达式,并弹出该栈顶元素,反复执行直到操作符的优先级大于或等于栈顶元素的优先级的时则将它压入栈中。
(5)重复上述步骤直到缀表达式的结束符标记“#“,弹出栈中所有元素并放入前缀表达,输出倒序输出。
转换结束。
后缀表达式的计算的基本思路:
使用一个栈和一个数组(栈是运算对象,数组是用来存放后缀表达式)用于表达式的计算。
从左到右遍历表达式的每一个数字和符号,遇到数字就进栈,遇到运算符号,就将栈顶的两个数字出栈,进行计算,运算结果进栈,直到获得最终结果结束。
二、算法流程图
图1中缀变后缀算法流程图
图2中缀变前缀算法流程图
图3后缀表达式计算算法流程图
三、源代码
下面给出的是用将中缀转换成后缀表达式算法实现的程序的源代码:
intchange(chara[],intn){
inti;
intj=0;
charx1,x2,bj;
charstack*q;
q=creat();
for(i=0;iif(a[i]<='9'&&a[i]>='0'){
s[j]=a[i];
j=j+1;
if(a[i+1]>'9'||a[i+1]<'0'){
s[j]='';
j=j+1;
}
}
else{
x1=a[i];
x2=top(q);
if(x2=='#')
q=push(q,x1);
else{
if(x1==')'){
while(top(q)!
='('){
s[j]=top(q);
j=j+1;
q=popl(q);
}
q=popl(q);//
}
else{
bijiao:
bj=compare(x1,x2);
switch(bj){
case'>':
q=push(q,x1);break;
case'<':
if(x2!
='('){
s[j]=top(q);
j=j+1;
q=popl(q);
x2=top(q);
if(x2!
='#')gotobijiao;
elseq=push(q,x1);break;
}
elseq=push(q,x1);break;
case'=':
s[j]=top(q);
j=j+1;
q=popl(q);
q=push(q,x1);break;
}
}
}
}
}
while(top(q)!
='#'){
s[j]=top(q);
j=j+1;
q=popl(q);
}
returnj;
}
下面给出的是用将中缀转换成前缀表达式算法实现的程序的源代码:
voidconvert(chars[N])//将中缀表达式转化为前缀表达式
{
charp[N],stack[N];
inttop=0,j=0,len=0;
if(s[0]==')')
{
printf("对不起,您输入不合法,将退出当前的程序!
");
printf("\n\n");
}
else
{
while(s[len]!
='\0')
{
len++;
}
for(inti=len-1;i>=0;)
{
if(s[i]>=48&&s[i]<=57)
{
while(s[i]>=48&&s[i]<=57)
{p[j]=s[i];
j++;i--;}
p[j]='';j++;
}
if(s[i]==')')//假如是右括号,将它压栈。
{
top++;
stack[top]=s[i];
}
while(Operator(s[i]))
{
if(top==0||stack[top]==')'||f(s[i])>=f(stack[top]))
{
top++;
stack[top]=s[i];break;
}
else
{
p[j]=stack[top];
top--;j++;
}
}
if(s[i]=='(')//假如是左括号,栈中运算符逐个出栈并输出,直到遇到右括号。
右括号出栈并丢弃。
{
while(stack[top]!
=')')
{
p[j]=stack[top];
top--;j++;
}
top--;
}
i--;
}
while(top!
=0)//假如输入完毕,栈中剩余的所有操作符出栈并加到输入串中
{
p[j]=stack[top];
j++;
top--;
}
p[j]='\0';
printf("转化成对应的前缀表达式为:
");
for(;j>=0;j--)
{
printf("%c",p[j]);
}
printf("\n\n");
}
}
下面给出的是用后缀表达式实验表达式计算的程序的源代码:
intcalculator(chars[],intn){//计算表达式的值
inti,x1,x2,x;
intstack*q;
q=intcreat();
for(i=0;i<=n;i++){
if(s[i]=='')i=i+1;
if(s[i]<='9'&&s[i]>='0'){
x1=(int)s[i]-48;
while(s[i+1]<='9'&&s[i+1]>='0'){
x1=10*x1+(int)s[i+1]-48;
i=i+1;
}
q=intpush(q,x1);
}
elseif(s[i]=='+'){
x2=inttop(q);
q=intpopl(q);
x1=inttop(q);
q=intpopl(q);
q=intpush(q,x1+x2);
}
elseif(s[i]=='-'){
x2=inttop(q);
q=intpopl(q);
x1=inttop(q);
q=intpopl(q);
q=intpush(q,x1-x2);
}
elseif(s[i]=='*'){
x2=inttop(q);
q=intpopl(q);
x1=inttop(q);
q=intpopl(q);
q=intpush(q,x1*x2);
}
elseif(s[i]=='/'){
x2=inttop(q);
q=intpopl(q);
x1=inttop(q);
q=intpopl(q);
q=intpush(q,x1/x2);
}
}
x=inttop(q);
returnx;
}
四、运行结果
运行程序,输入中缀表达式以#号结束,敲回车键显示后缀表达式、前缀表达式和计算结果,如图4所示。
图4中缀变后缀、前缀表达式的运行结果
五、遇到的问题及解决
这部分我主要遇到了如下两个问题,其内容与解决方法如下所列:
●如何将一位数变成两位数
解决方案:
在各数字之间用空格隔开,并且添加语句,主要思想是当第一个数字进栈后,判断下一个进栈的元素,若是数字元素则进栈,若是运算符,则加空格将其与其他数字分开,在前缀表达式求值语言中加入一下代码:
if(s[i]<='9'&&s[i]>='0'){
x1=(int)s[i]-48;
while(s[i+1]<='9'&&s[i+1]>='0'){
x1=((int)s[i+1]-48)*pow(10,j)+x1;
i=i+1;j++;
}
●生成后缀表达式时,如何将数和字符存放在一个字符串中
解决方案:
不把字符数组的数字都截取出来,而是把数字进行一个分割,让数字还依旧存放在数组中,只是在每个数字的后面都加上一个分割符号“”,然后要是遇到操作符也将操作符存放到这个数组中并且也加入分隔符,这样就组成了一个全新的数组,也即是后缀表达式。
这里的修改是遇到数字,边走边存,一个数字取完后就在数字的后面加分隔符。
如果是操作符,则进行优先级的判断,根据判断的结果把操作符加入到数组中,以生成后缀表达式。
六、心得体会
通过这该程序的编写,使我发现了学习上的一些问题,尤其在遇到指针的问题的时候,有种无从下手的感觉,在以后的学习中应注意指针的使用,以达到熟练掌握的程度。
学会了栈的使用,通过出栈、入栈使问题得到解决。
平时的学习中一定要多写程序,这样才能熟练运用知识,达到活学活用的程度。
其实大一就开始学习C语言,可是一遇到编程的问题还是头大,总感觉没有什么思路。
而这次实验,给自己一个不得不动手操作的机会,在这十几天中,通过网上搜索资料,然后一点一点的摸索,遇到了错误和同学一起讨论,有问题想办法解决,最后终于将程序调试出来了。
我知道,自己的水平还很差,要想学习好这门课,在以后的学习中就要多动手操作,实现书上的例题或算法,加深对算法的理解。
有时候,一些算法虽然理解了,但是在实现的时候还会产生许多错误。
因此在以后的练习和实践中,应该多动手,多思考,找到自己程序的不足,加以改正。
提高自己的编程能力,为以后的程序编写打好基础。