Implement a basic calculator to evaluate a simple expression string.
The expression string contains only non-negative integers, +
, -
, *
, /
operators and empty spaces . The integer division should truncate toward zero.
You may assume that the given expression is always valid.
Some examples:
"3+2*2" = 7 " 3/2 " = 1 " 3+5 / 2 " = 5
解法请参考 严蔚敏 数据结构 第52页,表达式求值,完全按照这本书写的来实现。
leetcode 224 Basic Calculator I ,这个代码也完全适用。
#include <iostream>
#include <string>
#include <stack>
using namespace std;
int calculate(string s);
char table[7][7] ={
//+ - * / ( ) #
{'>','>','<','<','<','>','>'}, // +
{'>','>','<','<','<','>','>'}, // -
{'>','>','>','>','<','>','>'}, // *
{'>','>','>','>','<','>','>'}, // /
{'<','<','<','<','<','=','%'}, // (
{'>','>','>','>','%','>','>'}, // )
{'<','<','<','<','<','%','='} // #
};
int main()
{
string s = "31 * (72 + (78 - 96)- 26)";
cout << calculate(s) << endl;
cout << "hello, world !" << endl;
system("pause");
return 0;
}
int calculate(string s)
{
string optr = "+-*/()#";
if(s.empty()) return 0;
s += "#";
stack<char> s_optr;
s_optr.push('#');// 运算符栈
stack<int> s_opnd;
int num = 0;
for(const char * p = s.c_str(); *p; ){
if(optr.find(*p) == string::npos){
if(isspace(*p)){
++p;
continue;
}
if(isdigit(*p)){
char * end_ptr;
num = strtol(p, &end_ptr, 10);
s_opnd.push(num);
p = end_ptr;
}
}
else{
int j = optr.find( *p);
int i = optr.find( s_optr.top() );
switch(table[i][j]){
case '<': // 栈顶元素优先权低
s_optr.push(*p);
++p;
break;
case '=': // 脱括号并接收下一个字符
s_optr.pop();
++p;
break;
case '>': //栈顶元素优先权高 退栈,并将运算结果入栈
char s_top = s_optr.top();
s_optr.pop();
int b = s_opnd.top();
s_opnd.pop();
int a = s_opnd.top();
s_opnd.pop();
switch(s_top){
case '+': s_opnd.push(a + b); break;
case '-': s_opnd.push(a - b); break;
case '*': s_opnd.push(a * b); break;
case '/': s_opnd.push(a / b); break;
}
break;
}
}
}
return s_opnd.top();
}