实验内容
题目:中缀表示形式的一位整数的简单算术表达式求值
基本内容:
输入一个中缀算术表达式,先将其转换为后缀表达式,转换的方法采用栈实现,并且考虑算符的优先级,然后用另一个栈来计算后缀表达式的值。对输入的表达式,做如下假设:
(1)只考虑+、-、*、/这四种运算符;
(2)输入的中缀表达式中数字是一位整数,没有小数;
(3)假定输入表达式是合法的。
选做内容:
如果表达式加入括号和乘方运算,算法和程序如何改变?
实验思路:
先将输入的中缀表达式通过比较符号的一个工具栈来改变为后缀表达式。遇到数字直接入栈,遇到运算符将其放入比较符号工具栈进行比较,如果新入栈的运算符优先级大于栈顶的优先级那么直接入栈,如果等于或低于栈顶优先级那么从栈顶到栈底弹出所有的运算符,放入后缀表达式栈。
当得到后缀表达式之后,通过另外一个操作栈来进行运算,从栈底向栈顶,若为数字那么直接出栈进入操作栈,遇到操作符,从操作栈里面弹出两个数字进行运算,并把结果放入操作栈里面,直至运算符遍历到‘=’为止。最后输出结果。
代码
#include <stdio.h>
#include <stdlib.h>
float calculate(float a,char ch,float b);/*计算函数*/
int judgeprior(char a,char b);/*比较两个运算符的优先级*/
int judgenum(char a);/*判断此字符是否含义为整形数字*/
float transnum(char a);/*将字符型转化为浮点型*/
int main()
{
char x[100]= {'\0'}/*比较符号栈*/,y[100]= {'\0'}/*后缀表达式栈*/,ch;
float z[100]= {0}/*运算后缀表达式栈*/;
int a=1,b=0,c=0;
x[0]='#';/*标记栈底*/
while (ch!='=')/*在输入的同时将中缀表达式转换为后缀表达式*/
{
scanf("%c",&ch);
if (judgenum(ch))/*如果输入的是数字直接入栈2*/
{
y[b]=ch;
b++;
}
else/*输入的不是数字先入栈1*/
{
if(judgeprior(x[a-1],ch))
{
x[a]=ch;/*倘若优先级大就直接入栈1*/
a++;
}
else/*优先级小于或者等于前面的字符就将里面的字符弹出至栈2*/
{
while (x[a-1]!='#')
{
y[b]=x[a-1];
x[a-1]='\0';
b++;
a--;
}
if (ch=='=')
{
y[b]='=';
break;/*将'='作为后缀表达式结束的标志*/
}
x[a]=ch;
a++;
}
}
}
b=0;/*将后缀表达式栈对应位置调回开头*/
while(y[b]!='=')/*用后缀表达式运算,当后缀表达式栈遍历的字符为=时就停止循环*/
{
if(judgenum(y[b]))/*如果这个字符含义是整形数字那么将其转换成整形后赋值给运算后缀表达式栈*/
{
z[c]=transnum(y[b]);
b++;
c++;
}
else /*这里一定是操作符所以从运算后缀表达式栈中弹出两个数字进行运算*/
{
z[c-2]=calculate(z[c-2],y[b],z[c-1]);
c--;
b++;
}
}
printf("%f",z[c-1]); /*输出结果*/
return 0;
}
float calculate(float a,char ch,float b)/*用来计算一个算式*/
{
float sum=0;
switch(ch)
{
case '+':
sum=a+b;
break;
case '-':
sum=a-b;
break;
case '*':
sum=a*b;
break;
case '/':
sum=a/b;
break;
default :
break;
}
return sum;
}
int judgeprior(char a,char b)/*优先级比较函数*/
{
int x,y;
if ((a=='#')||(a=='='))x=-1;
if ((a=='+')||(a=='-'))x=0;
if ((a=='*')||(a=='/'))x=1;
if ((b=='#')||(b=='='))y=-1;
if ((b=='+')||(b=='-'))y=0;
if ((b=='*')||(b=='/'))y=1;
if (x<y)return 1;/*如果入栈的运算符优先级大于栈顶的,返回1*/
else return 0;/*如果入栈的运算符优先级小于或等于栈顶的,返回0*/
}
int judgenum(char a)/*判断此字符是否含义为整形数字*/
{
if ('0'<=a&&a<='9')return 1;
else return 0;/*如果是数字则返回1,不是返回0*/
}
float transnum(char a)/*将字符型转化为浮点型函数*/
{
float i;
switch(a)
{
case '0':
i=0;
break;
case '1':
i=1;
break;
case '2':
i=2;
break;
case '3':
i=3;
break;
case '4':
i=4;
break;
case '5':
i=5;
break;
case '6':
i=6;
break;
case '7':
i=7;
break;
case '8':
i=8;
break;
case '9':
i=9;
break;
default :
i=-1;
break;
}
return i;
}
运行结果:
第一组:
输入数据:
2*2-3*4+5*6=
输出结果:
第二组:
输入数据:
9/3-9/2+8/4=
输出结果:
第三组:
输入数据:
2/2-8/4+3*9=
输出结果: