实验内容
①输入一个数学表达式(假定表达式输入格式合法),计算表达式结果并输出。
②数学表达式由单个数字和运算符“+”、“-”、“*”、“/”、“(、) ”构成,例如 2 + 3 * ( 4 + 5 ) - 6 / 4。
③变量、输出采用整数,只舍不入。
实验步骤
首先我参考了ppt的内容,总结出这类问题的解法。即:先把中缀表达式转换成后缀表达式,然后通过堆栈再把后缀表达式求值得出结果。
①中缀表达式转化成后缀表达式:
举例分析,中缀表达式a + b*c + (d * e + f) * g,其转换成后缀表达式则为a b c * + d e * f + g * +。转换过程需要用到栈,具体过程如下:
1)如果遇到操作数,我们就直接将其输出。
2)如果遇到操作符,则我们将其放入到栈中,遇到左括号时我们也将其放入栈中。
3)如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止。注意,左括号只弹出并不输出。
4)如果遇到任何其他的操作符,如(“+”, “*”,“(”)等,从栈中弹出元素直到遇到发现更低优先级的元素(或者栈为空)为止。弹出完这些元素后,才将遇到的操作符压入到栈中。有一点需要注意,只有在遇到" ) "的情况下我们才弹出" ( ",其他情况我们都不会弹出" ( "。
5)如果我们读到了输入的末尾,则将栈中所有元素依次弹出。
②后缀表达式求值:
从前向后扫描:
A.遇到数字,入栈
B.遇到符号,弹出两个数,然后计算(栈底的元素在前,栈顶的元素在后面),将计算的结果入栈
③编写程序:
定义两个栈和一个字符串
string aft;//存后缀表达式
stack<char>temp;//存符号
stack<int> ans;//保存结果
然后按逻辑编写两个方法,最后按要求输出。本次实验写了一个小时,调试bug用了两个小时,感觉逻辑没问题,反复看了十几遍代码,都没找到问题。最后发现,如果中缀表达式中的*无法消除符号栈中的内容时,一定要break,不然会陷入死循环,改正这个bug后程序就运行正常了。
④运行结果举例:
本次实验主要代码:
#include<bits/stdc++.h>
using namespace std;
string aft;//存后缀表达式
stack<char>temp;//存符号
stack<int> ans;//保存结果
void mid_to_aft(string &s){
for(int i=0;i<s.size();i++){
if( s[i]=='('){
temp.push(s[i]);
}
else if(s[i]==')'){
while(!temp.empty()){
if(temp.top()=='(')
{
temp.pop();
break;
}
aft.push_back(temp.top());
temp.pop();
}
}
else if(s[i]=='+'||s[i]=='-'){
while(!temp.empty()){
if(temp.top()=='('){
break;
}
else{
//cout<<temp.top();//
aft.push_back(temp.top());
temp.pop();
}
}
temp.push(s[i]);
}
else if(s[i]=='*'||s[i]=='/'){
while(!temp.empty()){
if(temp.top()=='('){
break;
}
else if(temp.top()=='*'||temp.top()=='/'){
//cout<<temp.top();//
aft.push_back(temp.top());
temp.pop();
}
else{
break;
}
}
temp.push(s[i]);
}
else if(s[i]>='0'&&s[i]<='9'){
aft.push_back(s[i]);
}
}
while(!temp.empty()){
aft.push_back(temp.top());
temp.pop();
}
}
void cal_and_print(string &s){
for(int i=0;i<s.size();i++){
if(s[i]>='0'&&s[i]<='9'){
ans.push((int)(s[i]-'0'));
}
else{
int num2=ans.top();
ans.pop();
int num1=ans.top();
ans.pop();
if(s[i]=='+'){
ans.push(num1+num2);
}
if(s[i]=='-'){
ans.push(num1-num2);
}
if(s[i]=='*'){
ans.push(num1*num2);
}
if(s[i]=='/'){
ans.push(num1/num2);
}
}
}
cout<<ans.top()<<endl;
}
int main(){
cout<<"Input"<<endl;
string input;
cin>>input;
cout<<"Output"<<endl;
mid_to_aft(input);
cal_and_print(aft);
cout<<"End0";
return 0;
}