中缀表达式求值是数据结构中栈的应用的一个典型,要学会使用C/C++语言书写中缀表达式求值并不难,关键在于方法得当(分析栈内外运算符的优先级)。
下面,我会将中缀表达式求值的代码模板呈现,同学们可以通过代码自行传递参数,分析计算机运行代码的每一步,进而达到熟悉计算机进行中缀表达式求值的步骤,以及熟练堆栈应用操作的目的。
代码中,我将中缀表达式求值的思路分为了两部分,首先要将中缀表达式转化为后缀表达式,然后再对后缀表达式求值。
#include <iostream>
#include <stack>
#include <string.h>
using namespace std;
int isp(char ch); // 栈内运算符优先级
int icp(char ch); // 栈外运算符优先级
char *InToPost(char *InString, int L); // 中缀表达式转后缀表达式
int PostExpEvaluation(char *str);// 后缀表达式求值
int main() {
char str[110];
gets(str);
int L = strlen(str);
strcpy(str, InToPost(str, L)); // 获得中缀表达式的后缀表达式
cout << PostExpEvaluation(str) << endl; // 后缀表达式求值
return 0;
}
int PostExpEvaluation(char *str) {
stack<int> s;
int x, y;
for(int i = 0; str[i] != '\0'; ++i)
{
if(str[i] != '+' && str[i] != '-' && str[i] != '*' && str[i] != '/') {// 如果不为运算符则运算数入栈
s.push(str[i] - '0');
}
else {// 栈中弹出两个运算符x、y才能运算,运算结果入栈
y = s.top();
s.pop();
if(s.empty()) {
cout << "Expression Error: " << y << endl; // 非正常终止,表达式有误
exit(0);
}
switch (str[i]) {
case '+':
x = s.top();
s.pop();
s.push(x+y);
break;
case '-':
x = s.top();
s.pop();
s.push(x-y);
break;
case '*':
x = s.top();
s.pop();
s.push(x*y);
break;
case '/':
if(y == 0) {
cout << "Error: " << y << "/0" << endl;// 非正常终止,除数为0
exit(0);
}
x = s.top();
s.pop();
s.push(x / y);
break;
}
}
}
x = s.top(); // 栈中仅剩的元素为最终结果
s.pop();
return x;
}
char *InToPost(char *InString, int L) {
stack<char> s;
int i = 0, j = 0;
char PostString[110];
s.push('#');
while(i < L) {
if(InString[i] != '#' && InString[i] != '+' && InString[i] != '-' && InString[i] != '*' && InString[i] != '/' && InString[i] != '(' && InString[i] != ')') {
PostString[j++] = InString[i++]; // 如果当前中缀表达式字符是操作数,则直接输出在后缀表达式中
}
else
{
if(isp(s.top()) < icp(InString[i])) {// 如果栈顶运算符优先级小于栈外运算符优先级,则栈外运算符入栈,i++
s.push(InString[i++]);
}
else if(isp(s.top()) == icp(InString[i])) {// 如果栈顶运算符优先级等于栈外运算符优先级,则栈顶运算符直接出栈,i++
s.pop(); i++;
}
else {
PostString[j++] = s.top();// 如果栈顶运算符优先级大于栈外运算符优先级,则栈顶运算符输出在后缀表达式并出栈
s.pop();
}
}
}
static char str[110]; // static定义变量在程序结束才释放内存,return返回static不会有警告
strcpy(str, PostString);// PostString是局部变量,函数调用结束后内存销毁,直接返回会警告出错
return str;
}
int isp(char ch) {
if(ch == '(')
return 1;
else if(ch == ')')
return 6;
else if(ch == '+')
return 3;
else if(ch == '-')
return 3;
else if(ch == '*')
return 5;
else if(ch == '/')
return 5;
else if(ch == '#')
return 0;
}
int icp(char ch) {
if(ch == '(')
return 6;
else if(ch == ')')
return 1;
else if(ch == '+')
return 2;
else if(ch == '-')
return 2;
else if(ch == '*')
return 4;
else if(ch == '/')
return 4;
else if(ch == '#')
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/5051d1e4b79763f37c44a154e66ad925.png)
切记!!!输入中缀表达式末尾要有#