编代码首先来说思路要清晰,这个问题看似无从下手,是因为我们大脑在想各种表达式的情况,其实不妨就先拿我们大脑计算表达式的方法想问题,先做小括号里的,再做乘除,然后是加减。小括号里的东西无非也是表达式,那么自然就想到了递归。涉及到递归,就要先找到相同的逻辑,然后是最后的结束条件。相同的逻辑是加减乘除,最后的结束条件是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;