(11)数据结构-栈应用-简易计算器

1、简介

离散数学中学过将中缀表达式转化为后缀表达式,再进行求解。因此,在求解中缀表达式结果时需要分两步。转化、求解。

1.1 转化

如何将一个中缀表达式转化为后缀表达式。
使用栈st1与栈st2,从左向右扫描中缀表达式

  • 如果是操作数,直接压入st1
  • 如果是操作符,考虑当前操作符与st2栈顶的优先级关系。
    – 如果高于栈顶的优先级,则直接压入st2
    –如果低于或等于栈顶的优先级,则将st2中所有操作符依次出栈并压入st1。 结束以后将当前操作符压入st2。
  • 扫描完中缀表达式以后,如果st2还有剩余操作符,那么将st2中操作符依次出栈压入st1。

1.2 求解

使用一个栈st,从左向右扫描后缀表达式

  • 如果是操作数,直接压入st,
  • 如果是操作符,将st次栈顶与st栈顶元素(注意顺序不能变)之间进行操作,运算结果压入st.。

2、 代码实现

#include<iostream>
#include<stack>
#include<string>
#include<cctype>
#include<map>


using namespace std;
typedef double ElemType;
bool flag = true;
map<char,int>op;

string Transfer(string s);
ElemType cal(string s);

int main(){
    
    
    string s;
    cin >> s;
    string sm = Transfer(s);
    cout << sm << endl;
    ElemType result = cal(sm);

    if(flag){
    
    
          cout << result;
      }else{
    
    
          cout << "ERROR" << endl;
      }


    return 0;

}
string Transfer(string s){
    
    
    stack<char> st1;
    stack<char> st2;
    op['*'] = op['/'] = 2;
    op['+'] = op['-'] = 1;

    for (int i = 0; i < s.length(); i++){
    
    
        char ch = s[i];
        if(isdigit(ch)){
    
    
            st1.push(ch);
            continue;
        }else{
    
    
            //如果该操作符的优先级低于或等于st2栈顶优先级
            //把st2中每一个操作福压到st1中
            while(!st2.empty() && op[ch] <= op[st2.top()]){
    
    
                st1.push(st2.top());
                st2.pop();
            }

            //结束以后,再将改操作符压入st2中
            st2.push(ch);
        }
    }

    //如果st2还有,全部压入st1即可
    while(!st2.empty()){
    
    
        st1.push(st2.top());
        st2.pop();
    }
    string st = s;
    for(int i = s.length()-1; i >= 0; i--){
    
    
        st[i] = st1.top();
        st1.pop();
    }

    return st;

}

ElemType cal(string s){
    
    
    stack<ElemType> st;
    for(int i = 0; i < s.length(); i++){
    
    
        char ch = s[i];
        if(isdigit(ch)){
    
    
            st.push(ch-'0');
        }else{
    
    
            ElemType b = st.top();
            st.pop();
            ElemType a = st.top();
            st.pop();
            ElemType c;

            switch (ch) {
    
    
                case '+':
                    c = a + b;
                    break;
                    case '-':
                        c = a -b;
                        break;
                        case '*':
                            c = a * b;
                            break;
                            case '/':
                                if(b == 0){
    
    
                                    flag = false;
                                    break;
                                }else{
    
    
                                    c = a / b;
                                }
                                break;
            }
            st.push(c);
        }
    }

    return st.top();
}

3、缺点
上面的代码只能解决操作数都为整数的情况,但是实际使用中,浮点数才是最常见的使用。

おすすめ

転載: blog.csdn.net/xdg15294969271/article/details/120470337