思路很简单,遇到数字直接进栈,遇到运算符也进栈,但是如果前面的运算符大于或者等于当前运算符就会弹出当前的栈顶,直到运算符栈为空或者栈顶运算符大于自己的优先级。
写法比较中规中矩,有什么写的不好的地方欢迎指教。
//用于获得运算符优先级
int getCode(char c){
if(c == '+') return 0;
if(c == '-') return 0;
if(c == '/') return 1;
if(c == '*') return 1;
return -1; //we can't find this operation
}
//弹出数字时用来计算栈顶元素
void calculate(stack<int>& nums, char operation){
int y = nums.top(); nums.pop();
int x = nums.top(); nums.pop();
if(operation == '+') nums.push(x + y);
if(operation == '-') nums.push(x - y);
if(operation == '*') nums.push(x * y);
if(operation == '/') nums.push(x / y);
}
int calculate(string s) {
if(s.empty()) return 0;
stack<int> nums; //定义两个栈 一个是数字栈 一个是运算符栈
stack<char> operations;
nums.push(0); //这个细节很关键,可以避免一开始是负数的情况 比如 -3, 我们这会处理成0 - 3 及-3
int p = 0;
while(p < s.size()){
if(s[p] != ' '){
if( s[p] >= '0' && s[p] <= '9' ){//处理数字
int ret = 0;
while(s[p] >= '0' && s[p] <= '9'){
ret = ret * 10 + (s[p++] - '0');
}
nums.push(ret);
}else{
//operations
if(operations.empty())//处理运算符
operations.push(s[p++]);
else{
while(!operations.empty() && getCode( operations.top() ) >= getCode(s[p])){//弹出大于等于自己优先级的运算符
calculate(nums, operations.top());
operations.pop();
}
operations.push(s[p++]);//入栈
}
}
}else p++;
}
//计算栈内剩下的元素
while(!operations.empty()){
calculate(nums, operations.top()); operations.pop();
}
//栈顶即为最后结果
return nums.top();
}