这里介绍中缀表达式求值的两种方法:
(1)、先将中缀表达式转化为后缀表达式,再利用后缀表达式求值算法计算,这里可看之前的文章,中缀表达式转化为后缀表达式和后缀表达式求值;
(2)、利用栈来实现,这里需要两个栈:数据栈和操作符栈,依次扫描字符串,遇到数据就压入数据栈中,遇到操作符,则判断其与操作符栈栈顶元素的优先级,这里可参考文章里的判断方法:中缀表达式转化为后缀表达式;
方法(2)的具体代码如下:(代码多位数运算存在bug,暂时没修改,大佬可以评论区修改)
#include<bits/stdc++.h>
using namespace std;
int yxj(char c)
{
if (c == '-' || c == '+')
return 1;
if (c == '*' || c == '/')
return 2;
return 3;
}
int jisuan(int a, char c, int b)
{
switch (c) {
case '+':return a + b;
case '-':return a - b;
case '*':return a * b;
case '/':return 1.0*a / b;
}
}
void duoweishu(stack<int> &s_number, int &flag) //将输入的多位数转化处理
{
int n=flag;
for (int i = 1; i <= n; i++)
{
int right = s_number.top();
s_number.pop();
int left = s_number.top();
s_number.pop();
s_number.push(right+left*pow(10,i));
flag--;
}
}
void yunsuan(stack<int>& s_number, char c) //将两个操作数出栈运算,结果继续入栈
{
int right = s_number.top();
s_number.pop();
int left = s_number.top();
s_number.pop();
s_number.push(jisuan(left, c, right));
}
int panduan(stack<int> &s_number, stack<char> &s_str, char c)
{
if(s_str.empty())
{
s_str.push(c);
return 0;
}
else
{
if (c == '(')
{
s_str.push(c);
return 0;
}
else if (c == ')')
{
while (s_str.top() != '(')
{
yunsuan(s_number, s_str.top());
s_str.pop();
}
s_str.pop();//将( 出栈
}
else
{
if (yxj(c) > yxj(s_str.top()))
{
s_str.push(c);
return 0;
}
else
{
if (s_str.top() != '(')
{
yunsuan(s_number, s_str.top());
s_str.pop();
return panduan(s_number, s_str, c);
}
if (s_str.top() == '(')
{
s_str.push(c);
return 0;
}
}
}
}
}
int main()
{
string s;
stack<int> s_number;//数据栈
stack<char> s_str;//操作符栈
while (cin >> s)
{
int flag = 0;//用来判断数字是个位数还是多位数
for (char c : s)
{
if (isdigit(c) != 0)//c是数字
{
s_number.push(c - '0');//将字符c转换为数字c
flag++;
}
else//c是操作符
{
flag--;
if (flag != 0)
duoweishu(s_number, flag);
panduan(s_number, s_str, c);
}
}
while (!s_str.empty())
{
duoweishu(s_number, flag);
yunsuan(s_number, s_str.top());
s_str.pop();
}
cout << s_number.top() << endl;
s_number.pop();
}
return 0;
}