【栈】表达式计算

151. 表达式计算4

写法一:

#include <iostream>
#include <stack>
#include <unordered_map>

using namespace std;

stack<char> op;
stack<int> num;

int qmi(int a, int k)
{
    int res = 1;
    while(k)
    {
        if(k & 1) res = res * a;
        a = a * a;
        k >>= 1;
    }
    return res;
}

void eval()
{
    int b = num.top(); num.pop();
    int a = num.top(); num.pop();
    char c = op.top(); op.pop();
    int x;
    if(c == '+') x = a + b;
    else if(c == '-') x = a - b;
    else if(c == '*') x = a * b;
    else if(c == '/') x = a / b;
    else if(c == '^') x = qmi(a, b);
    num.push(x);
}

int main()
{
    string s;
    cin >> s;
    
    unordered_map<char, int> pr{{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}, {'^', 3}};
    
    int l = 0, r = 0;
    for(int i = 0; i < s.size(); i ++ ) 
        if(s[i] == '(') l ++ ;
        else if(s[i] == ')') r ++ ;
    
    char c;
    if(l > r) c = ')';
    else if(l < r) c = '(';
    
    string add;
    for(int i = 0; i < abs(l - r); i ++ ) add += c;
    
    if(l > r) s = s + add;
    else if(l < r) s = add + s;
    
    for(int i = 0; i < s.size(); i ++ )
    {
        if(s[i] == '-' && i == 0) s = '0' + s;
        else if(s[i] == '-' && i > 0 && !isdigit(s[i - 1]) && s[i - 1] != ')')
        {
            s.insert(i - 1, "0");
            i ++ ;
        }
    }
    
    for(int i = 0; i < s.size(); i ++ )
    {
        if(isdigit(s[i]))
        {
            int j = i, x = 0;
            while(j < s.size() && isdigit(s[j]))
                x = x * 10 + s[j ++ ] - '0';
            num.push(x);
            i = j - 1;
        }
        else if(s[i] == '(') op.push(s[i]);
        else if(s[i] == ')') 
        {
            while(op.top() != '(') eval();
            op.pop();
        }
        else
        {
            while(op.size() && op.top() != '(' && pr[op.top()] >= pr[s[i]])
                eval();
            op.push(s[i]);
        }
    }
    while(op.size()) eval();
    cout << num.top() << endl;
    return 0;
}

写法二:

#include <iostream>
#include <stack>
#include <unordered_map>

using namespace std;

stack<int> num;
stack<char> op;

int qmi(int a, int k) //快速幂
{
    int res = 1;
    while(k)
    {
        if(k & 1) res = res * a;
        a = a * a;
        k >>= 1;
    }
    return res;
}

void eval()
{
    auto b = num.top(); num.pop();
    auto a = num.top(); num.pop();
    auto c = op.top(); op.pop();
    int x;
    if(c == '+') x = a + b;
    else if(c == '-') x = a - b;
    else if(c == '*') x = a * b;
    else if(c == '/') x = a / b;
    else if(c == '^') x = qmi(a, b);
    num.push(x);
}

int main()
{
    string s;
    cin >> s;
    
    if(s[0] == '-') s = '0' + s;
    unordered_map<char, int> pr{{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}, {'^', 3}};
    
    int l = 0, r = 0;
    
    for(int i = 0; i < s.size(); i ++ )
        if(s[i] == '(') l ++ ;
        else if(s[i] == ')') r ++ ;
        
    char c;
    if(l > r) c = ')';
    if(l < r) c = '(';
    
    string left;
    for(int i = 0; i < abs(l - r); i ++ ) left += c;
    
    if(l > r) s = s + left;
    if(l < r) s = left + s;
    
    for (int i = 1; i < s.size(); i ++ ) // 在所有负数前面添 0 
    {
        if (s[i] == '-' && i && !isdigit(s[i - 1]) && s[i - 1] != ')')
        {
            s.insert(i - 1, "0");
            i ++ ;
        }
    }
    
    for(int i = 0; i < s.size(); i ++ )
    {
        if(isdigit(s[i]))
        {
            int j = i, x = 0;
            while(j < s.size() && isdigit(s[j]))
                x = x * 10 + s[j ++ ] - '0';
            num.push(x);
            i = j - 1;
        }
        else if(s[i] == '(') op.push(s[i]);
        else if(s[i] == ')') 
        {
            while(op.top() != '(') eval();
            op.pop();
        }
        else
        {
            while(op.size() && op.top() != '(' && pr[op.top()] >= pr[s[i]])
                eval();
            op.push(s[i]);
        }
    }
    while(op.size()) eval();
    cout << num.top() << endl;
    return 0;
}
posted @   Tshaxz  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
Language: HTML
点击右上角即可分享
微信分享提示