蓝桥杯篇4 - 计算表达式

题目

问题描述
  输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。
输入格式
  输入一行,包含一个表达式。
输出格式
  输出这个表达式的值。
样例输入
1-2+3*(4-5)
样例输出
-4
数据规模和约定
  表达式长度不超过100,表达式运算合法且运算过程都在int内进行。

思路

* 略略的有些low * 将字符串遍历一次,声明一个栈,存放左括号(的位置,即遇到左括号(就push一下这个括号的位置。遇到右括号)就先得到与它对应的右括号(的位置,即top(), 再pop()一下,准备下次的偶遇。自己写一个calculate函数,用于计算两个括号之间的表达式,然后将得到的结果用replace函数替换两个括号()之间的表达式。这样遍历一遍之后,括号中的内容都已经计算出来了,并且没有括号了,再将表达式调用一遍calculate函数计算一遍即可得出正确的结果。

calculate函数思路

遍历一遍需要计算的字符串,判断其中的字符为*还是\,如果是,然后得到这个字符两边的数据,然后进行运算。
再遍历一遍需要计算的字符串,判断其中的字符为+还是-,如果是,然后得到这个字符两边的数据,然后进行运算。

需要注意的几点
  • 使用replace函数后记得将循环变量设置为被替换的的字符串中的(的位置,循环的下次需要从那里开始。
  • calculate函数取运算符两边的值的时候,需要注意可能是个负数,负数是有个-号的。
  • 这个代码中使用了 * c++11才支持的to_string函数 * ,这个函数可以把整数转换为字符串。蓝桥杯会出现编译错误,自己去写个吧。我就不写了。
  • * 还有最重要的一点,博主很cool !�� *

代码

#include <iostream>
#include "string"
#include "stack"
#include "math.h"
using namespace std;

string operate(int a1, int a2, char oper) {
    int result=0;
    if (oper=='+') {
        result=a1+a2;
    } else if (oper=='-') {
        result=a1-a2;
    } else if (oper=='*') {
        result=a1*a2;
    } else if (oper=='/') {
        result=a1/a2;
    }
    return std::to_string(result);
}


string calculate(string str) {
    int p, q;
    for (int i=0; i<=str.length(); i++) {  // 这个循环用来计算乘除法
        if (str[i]=='*' || str[i]=='/') {
            int rightNum=0;
            int leftNum=0;
            bool isNeg=false;
            for (p=i+1; p<str.length(); p++) {
                if (str[i+1]=='-'&&p==i+1) {
                    isNeg=true;
                    continue;
                }
                int d=str[p]-'0';
                if (0<=d && d<=9) {
                    rightNum=rightNum*10+d;
                } else {
                    break;
                }
            }
            if (isNeg) {
                rightNum=-rightNum;
            }
            for (q=i-1; q>=0; q--) {
                int d=str[q]-'0';
                if (0<=d && d<=9) {
                    leftNum=leftNum+d*pow(10, i-q-1);
                } else {
                    if(str[q]=='-'&&str[q]-'0'>=0) {
                        leftNum=-leftNum;
                        q--;
                    }
                    break;
                }
            }
            string temp=operate(leftNum, rightNum, str[i]);
            str=str.replace(q+1, p-1-q, temp);
            i=q+1;
        }
    }

    for (int i=0; i<=str.length(); i++) {  // 这个循环用来计算加减法
        if (str[i]=='+' || str[i]=='-') {
            int rightNum=0;
            int leftNum=0;
            bool isNeg=false;
            for (p=i+1; p<str.length(); p++) {
                if (str[i+1]=='-'&&p==i+1) {
                    isNeg=true;
                    continue;
                }
                int d=str[p]-'0';
                if (0<=d && d<=9) {
                    rightNum=rightNum*10+d;
                } else {
                    break;
                }
            }
            if (isNeg) {
                rightNum=-rightNum;
            }
            for (q=i-1; q>=0; q--) {
                int d=str[q]-'0';
                if (0<=d && d<=9) {
                    leftNum=leftNum+d*pow(10, i-q-1);
                } else {
                    if(str[q]=='-'&&str[q-1]-'0'<0) {
                        leftNum=-leftNum;
                        q--;
                    }
                    break;
                }
            }
            string temp=operate(leftNum, rightNum, str[i]);
            str=str.replace(q+1, p-1-q, temp);
            i=q+1;
        }
    }
    return str;
}



int main(int argc, const char * argv[]) {
    // insert code here...
    stack<int> leftStk;
    string inStr;
    string subStr;
    int left=0;
    cin>>inStr;
    for (int i=0; i<inStr.length(); i++) {
        if (inStr[i]=='(') {
            leftStk.push(i);
        } else if (inStr[i]==')') {
            left=leftStk.top();
            leftStk.pop();
            subStr=inStr.substr(left+1, i-left-1);
            inStr.replace(left, i-left+1, calculate(subStr));
            i=left;
        }
    }

    cout<<calculate(inStr)<<endl;

    return 0;
}
//(1+2)*(3+4)+4*(5+4)*6/7

其实我觉得我这个是比较麻烦的一种方法,可以百度一下逆波兰表达式

用逆波兰表达式这个方法应该挺好做的。我上一篇博客—24点就是用的这个方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值