这篇博客讲的超级好
//原理就是中缀表达式我们需要先转后缀表达式, 然后就可以求了.
int calculate(string s) {
vector<string> hou; // 后缀表达式
stack<char>st;
for (int i = 0 ; i < s.size() ; ++ i) { // 转后缀表达式
if (s[i] == ' ') continue;
if (s[i] >= '0' && s[i] <= '9') {
int tmp = 0;
while (i < s.size() && s[i] >= '0' && s[i] <= '9') {
tmp = tmp * 10 + (s[i] - '0');
++ i;
}
-- i;
hou.push_back(to_string(tmp));
}
else if (s[i] == '(') st.push(s[i]);
else if (s[i] == ')') {
while(st.top() != '(') {
hou.push_back(string(1, st.top()));
st.pop();
}
st.pop();
}
else {
if (s[i] == '*' || s[i] == '/') st.push(s[i]);
else {
while(!st.empty() && st.top() != '(') {
hou.push_back(string(1, st.top()));
st.pop();
}
st.push(s[i]);
}
}
}
while(!st.empty()) {
hou.push_back(string(1, st.top()));
st.pop();
}
stack<double>num; // 下面是求值过程
for (int i = 0 ; i < hou.size() ; ++ i) {
if (hou[i] == "+" || hou[i] == "-" || hou[i] == "*" || hou[i] == "/") {
double y = num.top(); num.pop(); // 先出来的被操作运算值
double x = num.top(); num.pop();
num.push(cal(x, y, hou[i]));
}
else num.push(stod(hou[i]));
}
return num.top();
}
double cal(double x, double y, string op) {
if (op == "+") return x + y;
if (op == "-") return x - y;
if (op == "*") return x * y;
if (op == "/") return x / y;
}
// 下面的稍显复杂, 不过先留着mark
下面附上代码实现:
###1:中缀表达式转后缀表达式Code
const int maxn = 1e3+5;
char zhong[maxn];
char hou[maxn];
stack<char>S;
void solve()
{//这个是只有单个整数和运算符,只是直观给出后缀表达式,计算的当然不一样.
scanf("%s",zhong);
int len = strlen(zhong);
int cnt = 0;
for(int i=0;i<len;i++){ //注意一个优先级问题!!!
if(zhong[i]>='0' && zhong[i]<='9') hou[cnt++] = zhong[i];
else{ //也要特别注意判断运算符优先级的问题.
if(zhong[i] == '(' ) S.push(zhong[i]);
else if(zhong[i] == ')' ){
while(!S.empty()){
char tmp = S.top();
S.pop();
if(tmp == '(' ) break;
hou[cnt++] = tmp;
}
}
else if(zhong[i] == '*' || zhong[i] == '/'){
while(!S.empty()){
char tmp = S.top();
if(tmp == '+' || tmp == '-' || tmp == '(') break;
S.pop();
hou[cnt++] = tmp;
}
S.push(zhong[i]);
}
else if(zhong[i] == '+' || zhong[i] == '-'){
while(!S.empty()){
char tmp = S.top();
if(tmp == '(') break;
S.pop();
hou[cnt++] = tmp;
}
S.push(zhong[i]);
}
}
}
while(!S.empty()){ //有可能运算符还有.
char tmp = S.top();
S.pop();
hou[cnt++] = tmp;
}
hou[cnt] = 0;
printf("%s\n",hou);
}
模板题
###2 : 四则运算表达式求值(有了以上的基础,这个就比较简单)
Code
const int maxn = 1e3+5;
char zhong[maxn];
char hou[maxn];
char num[maxn];
db res[maxn];
stack<char>S;
stack<db>cal;
void solve()
{
while(~scanf("%s",zhong)){
Fill(hou,0); Fill(num,0); Fill(res,0);
int len = strlen(zhong);
int cnt = 0;
for(int i=0;i<len;i++){
if(zhong[i]>='0' && zhong[i]<='9'){
int ans = 0;
Fill(num,0);
while((zhong[i]>='0' && zhong[i]<='9') || zhong[i] == '.'){
num[ans++] = zhong[i];
i++;
}
i--;
res[cnt++] = atof(num);
}
else{
if(zhong[i] == '(' ) S.push(zhong[i]);
else if(zhong[i] == ')' ){
while(!S.empty()){
char tmp = S.top();
S.pop();
if(tmp == '(' ) break;
hou[cnt++] = tmp;
}
}
else if(zhong[i] == '*' || zhong[i] == '/'){
while(!S.empty()){
char tmp = S.top();
if(tmp == '+' || tmp == '-' || tmp == '(') break;
S.pop();
hou[cnt++] = tmp;
}
S.push(zhong[i]);
}
else if(zhong[i] == '+' || zhong[i] == '-'){
while(!S.empty()){
char tmp = S.top();
if(tmp == '(') break;
S.pop();
hou[cnt++] = tmp;
}
S.push(zhong[i]);
}
}
}
while(!S.empty()){ //有可能运算符还有.
char tmp = S.top();
S.pop();
hou[cnt++] = tmp;
}
for(int i=0;i<cnt;i++){
if(hou[i] == 0) cal.push(res[i]);
else{ //注意这些的写法与之前的处理的关系.
db t1 = cal.top();
cal.pop();
db t2 = cal.top();
cal.pop();
if(hou[i] == '+' ) cal.push(t1+t2);
if(hou[i] == '-' ) cal.push(t2-t1);
//注意数被取出来的先后顺序(-和/运算有影响).
if(hou[i] == '*' ) cal.push(t1*t2);
if(hou[i] == '/' ) cal.push(t2/t1);
}
}
printf("%.2f\n",cal.top());
cal.pop();
}
}