手动实现加减乘法并识别错误括号

这篇博客介绍了一个C++实现的算法,用于处理包含括号、加减乘运算的数字字符串表达式。算法首先通过栈结构检查括号匹配并计算中间结果,然后处理剩余的操作数和运算符,最终返回计算结果。测试用例展示了正常及异常情况的处理,包括无效的括号匹配和空字符串等。
摘要由CSDN通过智能技术生成

从实验室同学那里听来的题目,说好麻烦,今天自己试了试,发现确实好麻烦。

/*
 问题:// 字符串只有0-9的数字、括号和加减乘,实现运算。要判断表达式中括号是否匹配,给出计算结果
//不匹配的情况只有括号不匹配,表达式本身一定是合法的。
*/
string calculator(string s){
    //判断异常情况
    if(s.empty()) return to_string(0); //字符串为空
    int n = s.size();
    if(n == 1 && isdigit(s[0])) return s; //字符串只有一个字符,且是数字
    if(n == 1 && (s[0]=='(' || s[0] == ')')) return  "Invalid Parenthesis"; 
    //字符串只有1个字符且为括号,题目里没有要求判定这类异常输入,因此没有做判定
    
    stack<int> nums; //保存操作数
    stack<char> ops; //保存符号和左括号
    
    for(int i = 0 ; i < n ; i++){
        if(s[i] == '('){ //左括号入操作栈
            ops.push(s[i]);
        }
        else if(isdigit(s[i])){ //数字入数字栈,如果不是0~9,就在这里加个while,获取一个多位整数
            nums.push(s[i]-'0');
        }
        else if(s[i] == ')'){ //当识别到一个右括号,将上一个左括号以内的操作运算完
            int temp = 0;
            while(!ops.empty() && ops.top()!='('){
                switch (ops.top()) {
                    case '+':
                        temp += nums.top();
                        break;
                    case '-':
                        temp -= nums.top();
                        break;
                    case '*':
                        temp *= nums.top();
                }
                ops.pop(); //将操作符出栈
                nums.pop();
            }
            if(!nums.empty() && !ops.empty() && ops.top()=='('){
            //此时,正常的括号匹配下,将最后一个数字拿出,加在temp上,将temp推入数字栈,替代当前的括号
            //此时op的顶部应当是左括号
                temp += nums.top();
                nums.pop();
                nums.push(temp);
                ops.pop();
            }
            else{
            //其他情况都是异常
                return "Invalid Parenthesis";
            }
        }
        else{
            ops.push(s[i]); //操作符进栈
        }
    }
    int ans = 0;
    int x,y;
    while(!nums.empty()){
    //此时ops栈和nums栈内的操作数都是同一优先级了,因为高优先级在识别右括号时运算过了
        if(!ops.empty()){
            switch (ops.top()) {
                case '+':
                    ans += nums.top();
                    nums.pop();
                    ops.pop();
                    break;
                case '-':
                    ans -= nums.top();
                    nums.pop();
                    ops.pop();
                    break;
                case '*':
                    //switch中不能自定义变量 int x
                    x = nums.top();nums.pop();
                    y = nums.top();nums.pop();
                    nums.push(x*y);
                    ops.pop();
                    break;
                case '(':
                    return  "Invalid Parenthesis";
            }

        }
        else{
            ans += nums.top();
            nums.pop();
        }
    }
    
    return to_string(ans);
}

测试代码如下:

    cout<<"1+2*3 = "<<calculator("1+2*3")<<endl;
    cout<<"1 = "<<calculator("1")<<endl;
    cout<<"(1-(2+3))*5 = "<<calculator("(1-(2+3))*5")<<endl;
    cout<<"((1+3)*2 = "<<calculator("((1+3)*2")<<endl;
    cout<<"(1+3)*2 = "<<calculator("(1+3)*2")<<endl;
    cout<<"() = "<<calculator("()")<<endl;
    cout<<"( = "<<calculator("(")<<endl;
    cout<<") = "<<calculator(")")<<endl;

结果如下:

1+2*3 = 7
1 = 1
(1-(2+3))*5 = -20
((1+3)*2 = Invalid Parenthesis
(1+3)*2 = 8
() = Invalid Parenthesis
( = Invalid Parenthesis
) = Invalid Parenthesis
Program ended with exit code: 0

欢迎大家来试错+挑剔代码!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值