思路:通过逆波兰表达式求值的方法进行求解,可以有效的解救括号问题,因为后缀式不需要用括号来确定优先级。
解救方案:
1、中缀式转为后缀式
(1)
(2) 算法实现
(a) 定义一个空栈s,和一个string数组suffix
(b)对中缀表达式每个字符进行逐个接收。
(c)如果得到的是数字或者小数点,直接按顺序存到suffix内
(d)如果得到的是‘(’,压入栈中。
(e)如果得到的是‘)’,栈顶出栈存到suffix内,直至栈顶元素为‘)’,然后栈顶出栈,这一步可以解决小括号的问题。
(f)如果得到的是运算符,则将此与栈顶元素进行比较,如果优先级小于栈顶元素,则将栈顶元素存到suffix中,并且出栈,然后继续将栈顶元素与该运算符比较,直至该运算符大于栈顶元素,则将其入栈。
(g)遍历结束后,将栈内元素出栈,存到suffix内。至此,suffix就是按照后缀式的顺序存储的了。
2、后缀式运算
(1)依照从左到右的顺序读取suffix,如果得到的是操作数或者‘.’,则将其读取完整后处理为数字格式入栈,如果是运算符,则进行计算,计算该运算符栈顶的两个元素,将该两个栈顶元素依次出栈,新得的结果入栈。
(2)读取结束后,栈底等于栈顶且为最后运算结果,则运算正确。
code:
#include<iostream>
#include<cstdio>
#include<string>
#include<stack>
using namespace std;
int weight(char a) // 运算符权重
{
if(a == '+' || a == '-')
return 1;
else if(a == '*' || a == '/')
return 2;
else
return 0;
}
int midtosuffix(string &mids,string &suffixs) //中缀式转后缀式
{
stack<char > s; //用来处理括号问题
s.push('#');
int i = 0;
while(i < mids.length()-1)
{
if(mids[i] == '(')
{
s.push(mids[i]);
i++;
}
else if(mids[i] == ')')
{
while(s.top() != '(')
{
suffixs += s.top();
suffixs += ' ';
s.pop();
}
s.pop();
i++;
}
else if(mids[i] == '+' || mids[i] == '-' || mids[i] == '*' || mids[i] == '/')
{
while(weight(s.top()) >= weight(mids[i]))
{
suffixs += s.top();
suffixs += ' ';
s.pop();
}
s.push(mids[i]);
i++;
}
else
{
while(mids[i] >= '0' && mids[i] <= '9' || mids[i] == '.')
{
suffixs += mids[i++];
}
suffixs += ' ';
}
}
while(s.top() != '#')
{
suffixs += s.top();
suffixs += ' ';
s.pop();
}
}
double cal(string suffixs)//后缀表达式的运算
{
stack<double> s;
int i = 0;
double x,y;
while(i < suffixs.length())
{
if(suffixs[i] == ' ')
{
i++;
continue;
}
if(suffixs[i] == '+')
{
x = s.top();
s.pop();
x += s.top();
s.pop();
i++;
}
else if(suffixs[i] == '-')
{
x = s.top();
s.pop();
x = s.top() - x;
s.pop();
i++;
}
else if(suffixs[i] == '*')
{
x = s.top();
s.pop();
x *= s.top();
s.pop();
i++;
}
else if(suffixs[i] == '/')
{
x = s.top();
s.pop();
x = s.top()/x;
s.pop();
i++;
}
else
{
x = 0;
while(suffixs[i] >= '0' && suffixs[i] <= '9')
{
x *= 10;
x += suffixs[i]-'0';
i++;
}
if(suffixs[i] == '.')
{
y = 0;
double k = 10.00;
i++;
while(suffixs[i] >= '0' && suffixs[i] <= '9')
{
y += (suffixs[i]-'0')/k;
k *= 10.00;
i++;
}
x += y;
}
}
s.push(x);
}
return s.top();//返回运算结果
}
int main()
{
int n;
scanf("%d",&n);
string mids,suffixs;
while(n--)
{
cin>>mids;
suffixs = "";
midtosuffix(mids,suffixs);
cout<<suffixs<<" ="<<endl;
//printf("%.2f\n",cal(suffixs));
}
}