堆栈实现的数学运算表达式计算

堆栈实现的数学运算表达式计算

此处运算表达式为简单数学运算表达式,只包含+,-,*,/,及(,)
输入的为一个String字符串
输入

>  cout << "Input" << endl;
    string a;
    cin >> a;
    MatchedPairs(a);

首先进行括号匹配

> void MatchedPairs(string expr) {
    linkedStack<int> s;
    //创建一个栈
    int length = (int) expr.size();
    for (int i = 0; i < length; ++i) {
        if (expr.at(i) == '(')
            s.push(i);//如果遇到左括号,则压进栈中
        else if (expr.at(i) == ')') {
            //如果遇到右括号则和栈顶元素匹配,一个右括号一定是与离自己最近的左括号进行匹配
            int c = op(expr.substr(s.top() + 1, i - s.top() - 1));
            //将没有括号的字符串送入op函数进行运算并返回
            stringstream ss1;
            ss1 << c;
            string s1 = ss1.str();
            //将int转化为string
            int length2 = (int) s1.size();
            expr.replace(s.top(), i - s.top() + 1, s1);
            //结果替换送去计算的string
            length = length - (i - s.top() + 1) + length2;
            i = i - (i - s.top() + 1) + length2;
            //改变string长度及i
            s.pop();
        }
    }

op函数,没有括号的数学表达式进行运算
这里需要用到stoi(string)函数
string str=“154+33”
int a=stoi(str);
则a=154;
stoi()就是用于提取string中符号之前的数字的函数
但是有些编译器不支持,所以在这里提供一个自己写的

> int sto(string a) {
    int length = (int) a.size();
    int z = a.at(0) - '0';
    for (int i = 1; i < length; ++i) {
        if (a.at(i) >= '0' && a.at(i) <= '9') {
            z = (a.at(i) - '0') + z * 10;
        } else
            break;
    }
    return z;
}

与stoi()功能相同
现在来看看op()函数

int op(string str) {
    int a = sto(str);
    stringstream ss;
    ss << a;
    string str2 = ss.str();
    //先判断是否需要运算,即传入的是不是只是一个数字
    if (str2 == str) {
        return a;//如是,则直接返回
    }else {
        linkedStack<int> s;
        int length = (int) str.size();
        linkedStack<int> s2;
        //创建两个栈,一个用于存放运算符,一个用于存放数字
        for (int i = 0; i < length; ++i) {
            if (str.at(i) == '-') {
                if (i == 0 || (str.at(i - 1) < '0' || str.at(i - 1) > '9')) {
                    int k = -(sto(str.substr(i + 1, length)));
                    s2.push(k);//判断第一个数是不是负数
                } else {
                    if (!s.empty()&&s.top()=='-'){
                        int i = s2.top();
                        s2.pop();
                        int j = s2.top();
                        s2.pop();
                        s2.push(j-i);
                        s.pop();
                    }//如果之前已经有-存入则先计算
                    s.push('-');//否则存入
                }
            } else if (str.at(i) == '+') {
                if (!s.empty()&&s.top()=='-'){
                    int i = s2.top();
                    s2.pop();
                    int j = s2.top();
                    s2.pop();
                    s2.push(j-i);
                    s.pop();
                }//如果之前已经有-存入则先计算,-的优先级高于+
                s.push('+');//否则存入
            } else if (str.at(i) >= '0' && str.at(i) <= '9') {
                int k = sto(str.substr(i, length));
                s2.push(k);//将数字存入存入数字栈
            } else if (str.at(i) == '*' || str.at(i) == '/') {
                //遇到*或/直接运算后存入
                int k = sto(str.substr(i + 1, length));
                int j = s2.top();
                s2.pop();
                if (str.at(i) == '*') {
                    s2.push(k * j);
                } else {
                    s2.push(j / k);
                }
                i++;
            }
        }
        while (!s.empty()) {
            //将符号栈中剩余的符号运算完
            int i = s2.top();
            s2.pop();
            int j = s2.top();
            s2.pop();
            cout << "(" << i << "," << j << ")";
            if (s.top() == '-') {
                s2.push(j - i);
                s.pop();
            } else {
                s2.push(j + i);
                s.pop();
            }
        }
        return s2.top();
    }
}

到此op返回MatchedPairs再返回main,则计算完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值