简单计算只包含()和+-*/的表达式
思路:先将中缀表达式转化为后缀表达式,然后计算后缀表达式的值。
规则:时刻保证栈内 上面的元素 比 下边的元素 优先级高
步骤:
1.如果当前元素 比 栈顶元素 优先级 高,那么把当前元素压入栈内能保证规则成立,所以直接压栈。
2.如果当前元素 比 栈顶元素 优先级 低,那么把栈顶元素弹出放到后缀表达式里。
3.重复第二步,直到 当前元素 比 栈顶元素 优先级 高,则当前元素压入栈内能保证规则成立,所以直接压栈。
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <stack>
using namespace std;
int main(){
string s;///存原表达式
stack <char> res;///将原表达式转化为后缀表达式所用到的符号栈
cin>>s;
string behind[100];///存后缀表达式的字符串数组
int cnt = 0;///后缀表达式中字符串的个数(下标)
///把前缀表达式转化为后缀表达式
for(int i = 0;i<s.length();){
if(s[i]>='0' && s[i]<='9'){///以数字打头的一定是数字
char temp[10];///暂时放这个数
int t1 = 0;///这个数变成字符串时的长度(下标)
while(s[i]>='0' && s[i]<='9'){///如果有小数可以加上s[i]=='.'
temp[t1] = s[i];
i++;
t1++;
}
temp[t1]=0;///结束符,标志字符串已经结束
///数已经处理好了,直接存放到后缀表达式里
behind[cnt] = temp;
cnt++;
}
else{///如果是符号
if(s[i] == '('){///左括号直接压栈
res.push(s[i]);
}
else if(s[i] == ')'){///把左括号后的符号依次弹出,写入后缀表达式中
while(!res.empty() && res.top() != '('){
string temp = " ";///声明一个string类型变量,内存空间是一个字符大小
temp[0] = res.top();
behind[cnt] = temp;
cnt++;
res.pop();
}
res.pop();///弹出(但是不写进后缀表达式
}
else if(s[i] == '+' || s[i] == '-'){///把 + - * / 弹出并写入后缀表达式
while(!res.empty() && res.top() != '('){
string temp = " ";
temp[0] = res.top();
behind[cnt] = temp;
cnt++;
res.pop();
}
res.push(s[i]);
}
else{///把* / 弹出并写入后缀表达式
while(!res.empty()&&(res.top()=='*'||res.top()=='/')){
string temp = " ";
temp[0] = res.top();
behind[cnt] = temp;
cnt++;
res.pop();
}
res.push(s[i]);
}
i++;
}
}
while(!res.empty()){///把栈内剩余符号依次放入后缀表达式中
string temp = " ";
temp[0] = res.top();
behind[cnt] = temp;
cnt++;
res.pop();
}
cout<<"后缀表达式:"<<endl;
for(int i = 0;i<cnt;++i){
cout<<behind[i]<<" ";
}
///计算后缀表达式的值
stack<double> q;///计算表达式值的栈
bool error = 0;///表达式合法性判断
for(int i = 0; i<cnt; i++){
///如果是符号
if((behind[i][0]== '+' || behind[i][0]=='-' || behind[i][0]=='*' || behind[i][0]=='/')){
if(q.size()<2) {error = 1; break;}
double aa = q.top(); q.pop();
double bb = q.top(); q.pop();
if(behind[i][0]== '+') q.push(aa+bb);
else if(behind[i][0]== '-') q.push(bb-aa);///这里注意顺序,栈顶元素是减数
else if(behind[i][0]== '*') q.push((aa*bb));
else if(behind[i][0]== '/') {
if(bb==0){error = 1; cout<<"除0 ";break;}///排除除零错误
q.push(bb/aa);///注意顺序
}
}
else{
/// c_str() 函数是string中转化为字符数组的函数
///atof() 是c语言中将字符数组转化为浮点型数据函数
double x = atof(behind[i].c_str());
q.push(x);
}
}
if(q.size() != 1) error = 1;
if(error) cout<<"ERROR";
else cout<<endl<<"结果是:"<<q.top();
return 0;
}