堆栈应用(后序表达式)
堆栈应用之后序表达式
要求设计一个程序,能读取一个合法的中序表达式,将其转化为后序表达式并计算求值,输入的表达式可包括“+”“-”“*”“/”、正整数与圆括号,以“ # ”表示一个数字结束。
这里,我们可以考虑堆栈思想来实现整个操作过程。
首先,我们使用两个堆栈分别来储存结果与操作符,用一个字符串来储存中序表达式。至于有何作用我们待会儿再说。
#include<iostream> #include<cstdlib> #define maxn 10001 using namespace std; char exp[maxn];//储存转换后的后序表达式 char stack[maxn];//作为栈使用 char str[maxn];//储存输入的中序表达式
紧接着,让我们来思考一个中序表达式的转换过程。
依次对字符串str进行扫描:
1.若所得字符为数字则直接存入exp;
2.若所得字符为左括号则直接入栈;
3.若所得字符为右括号,则将栈中位于对应的左括号之上的操作符全部存入exp并出栈,然后将该左括号删除;
4.若所得字符为“+”“-”,则将栈顶端连续的“*”或“/”操作符全部存入exp并出栈,然后将该操作符存入栈中(因为优先级最低);
5.若所得字符为“*”“/”,则将栈顶端连续的“*”或“/”全部存入exp并出栈,再将该操作符存入栈;
6.若所得字符为“ # ”,则将当前栈中的所有运算符存入exp并出栈。
这里我们举出表达式a+(b*c*e+d+f)的转化过程:
1.a直接存入exp;
2.“+”入栈;
3.“( ”入栈;
4.b直接存入exp;
5.“*”入栈;
6.c直接存入exp;
7.栈顶“*”存入exp,并把当前扫描到的“*”存入栈中;
8.将e存入exp中;
9.将栈顶“*”存入exp,并把当前扫描到的“+”存入栈中;
10.将d直接存入exp中;
11.将“+”存入栈中;
12.将f存入exp;
13.将栈中左括号之上的所有操作符存入exp;
14.将栈中剩余操作全部存入exp,转化完毕!
最后,我们得到的结果为abc*e*df+++ .
至于后序表达式的计算,我们详见代码。
后序表达式(堆栈实现)代码如下:
//求表达式值 #include <cstdio> #include<cstdlib> #define MAX 100 char exp[MAX]; /*存储转换成的后缀表达式*/ # void trans() /*将算术表达式转换成后缀表达式*/ { char str[MAX]; /*存储原算术表达式*/ char stack[MAX]; /*作为栈使用*/ char ch; int sum,i,j,t,top=0; /*t作为exp的下标,top作为stack的下标,i作为str的下标*/ printf("***************************************************************\n"); printf("* 输入一个求值的表达式,以#结束。只能包含+,-,*,/运算符和正整数 *\n"); printf("***************************************************************\n"); printf("算术表达式:"); i=0; /*获取用户输入的表达式*/ do { i++; scanf("%c",&str[i]); } while (str[i]!='#' && i!=MAX); sum=i; /*记录输入表达式总的字符个数*/ t=1;i=1; ch=str[i];i++; while (ch!='#') { switch(ch) { case '(': /*判定为左括号*/ top++;stack[top]=ch; break; case ')': /*判定为右括号*/ while (stack[top]!='(') { exp[t]=stack[top];top--;t++; } top--; break; case '+': /*判定为加减号*/ case '-': while (top!=0 && stack[top]!='(') { exp[t]=stack[top];top--;t++; } top++;stack[top]=ch; break; case '*': /*判定为'*'或'/'号*/ case '/': while (stack[top]=='*' || stack[top]=='/') { exp[t]=stack[top];top--;t++; } top++;stack[top]=ch; break; case ' ':break; default: while (ch>='0' && ch<='9') /*判定为数字*/ { exp[t]=ch;t++; ch=str[i];i++; } i--; exp[t]='#';t++; } ch=str[i];i++; } while (top!=0) { exp[t]=stack[top];t++;top--; } exp[t]='#'; printf("\n\t原来表达式:"); for (j=1;j<sum;j++) printf("%c",str[j]); printf("\n\t后缀表达式:",exp); for (j=1;j<t;j++) printf("%c",exp[j]); } void compvalue() /*计算后缀表达式的值*/ { float stack[MAX],d; /*作为栈使用*/ char ch; int t=1,top=0; /*t作为exp的下标,top作为stack的下标*/ ch=exp[t];t++; while (ch!='#') { switch (ch) { case '+':stack[top-1]=stack[top-1]+stack[top]; top--;break; case '-':stack[top-1]=stack[top-1]-stack[top]; top--;break; case '*':stack[top-1]=stack[top-1]*stack[top]; top--;break; case '/':if (stack[top]!=0) stack[top-1]=stack[top-1]/stack[top]; else { printf("\n\t除零错误!\n"); exit(0);/*异常退出*/ } top--;break; default:d=0; while (ch>='0' && ch<='9') /*判定为数字字符*/ { d=10*d+ch-'0'; /*将数字字符转换成对应的数值*/ ch=exp[t];t++; } top++; stack[top]=d; } ch=exp[t];t++; } printf("\n\t计算结果:%g\n",stack[top]); } int main() { trans(); compvalue(); system("pause"); }
以上就是代码实现了!
若有不足,请指正!