编代码首先来说思路要清晰,这个问题看似无从下手,是因为我们大脑在想各种表达式的情况,其实不妨就先拿我们大脑计算表达式的方法想问题,先做小括号里的,再做乘除,然后是加减。小括号里的东西无非也是表达式,那么自然就想到了递归。涉及到递归,就要先找到相同的逻辑,然后是最后的结束条件。相同的逻辑是加减乘除,最后的结束条件是string 的标记位置pos等于字符串的长度,或者检查到单个字符等于')'。在实现的细节上先看下代码

补充:计算出的值应该是double类型。虽然整型过了,但是代码是不严谨的,因为表达式里有除号。

#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
int pos=0;
int calculate(string exp){
  vector<int> number={0};
  int num=0,sum=0;
  char tab='+';
  int len=exp.size();
  while(pos<len){
     num=0;
     if(exp[pos]=='('){
        pos++;
        num=calculate(exp);
    }
    /*检查数字*/
    while(pos<len && isdigit(exp[pos])){
        num=num*10+exp[pos]-'0';
        pos++;
    }
    /*数字存储*/
    switch (tab)
    {
        case '+':
            number.push_back(num);
            break;
        case '-':
            number.push_back(-num);
            break;
        case '*':
            number.back()=number.back()*num;
            break;
        case '/':
            number.back()=number.back()/num;
            break;
        default:
            break;
    }
    if(exp[pos]==')'){
        pos++;
        tab=exp[pos];
        break;
    }
    tab=exp[pos];
    pos++;
  }
  /*数字相加*/
  auto it=number.begin();
  while(it!=number.end()){
    sum=sum+*it;
    it++;
  }
  return sum;
}
int main(void){
    string expression;
    while(cin>>expression){
        pos=0;
        cout<<calculate(expression)<<endl;
    }
    return 0;
}

这里要关注的点是在计算表达式时,先把数字存储起来,乘除的运算在存储时就应处理,为了方便后续的计算。 在说下string 类型的size()和length()的区别。 这两个函数计算的结果值是一样的,都是字符串的长度不包含结束符。length()是考虑到传统C的strlen而设置的,size是考虑到STL作为一个容器应该具有自己的成员函数。

(1)当 string 中含有空字符’\0’,使用 strlen() 获取 string 的长度时会被截断,使用成员函数 length() 和 size() 可以返回 string的真实长度。 (2)cout 对 string 输出时,会过滤掉空字符,输出不会被截断。 (3)在构造或者拼接 string 时,建议同时指定 string 的长度,比如:

string strTest(buf,6);
// 而非,因为会被截断
string strTest(buf);

// 拼接时使用
strTest.append(buf,6);
// 而非,因为会被截断
strTest+=buf;