描述:实现一个计算器,字符串中只包含非负整数,+,-,*,/和空格
Example1: Input: "3+2*2" Output: 7
Example2: Input: " 3/2 " Output: 1
这道题相对来说还是比较简单的,不需要考虑括号及其他运算,但是我做的答案还是有一些问题,先贴一个个人觉得比较好的代码
class Solution {
public:
int calculate(string s) {
stack<int> res;
stringstream ss('+' + s); //在整个字符串前面增加一个“+”作为第一个数字的符号
int n;
char op;
while(ss >> op >> n) { //stringstream这种用法值得学习,同时也排除了空格的影响
if(op == '+') {
res.push(n);
}
if(op == '-')
res.push(-n);
if(op == '*') {
int ans = res.top() *n;
res.pop();
res.push(ans);
}
if(op == '/') {
int ans = res.top() /n;
res.pop();
res.push(ans);
}
}
int ans=0;
while(res.size()!=0) {ans+=res.top(); res.pop();}
return ans;
}
};
下面是我的代码,建了两个栈——符号栈和数字栈,通过比较不同符号之间的优先级大小确定顺序,debug很久 一些小细节很容易出错
class Solution {
public:
int cal(int num1, int num2, char c)
{
int num = 0;
switch(c)
{
case '+': num = num1 + num2; break;
case '-': num = num1 - num2; break;
case '*': num = num1 * num2; break;
case '/': num = num1 / num2; break;
default:
break;
}
return num;
}
int calculate(string s) {
map<char, int> priority;
stack<int> num;
stack<char> opt;
priority['+'] = 0;
priority['-'] = 0;
priority['*'] = 1;
priority['/'] = 1;
int size = s.size();
int i = 0;
while(i < size)
{
while(i < size && s[i] == ' ')
{
i++;
}
if(i < size && s[i] >= '0' && s[i] <= '9')
{
int number = 0;
while(i < size && s[i] >= '0' && s[i] <= '9')
{
number = number * 10 + (s[i] - '0');
i++;
}
num.push(number);
}
else if(i < size)
{
if(opt.empty() || priority[s[i]] > priority[opt.top()])
opt.push(s[i]);
else
{
while(!opt.empty() && priority[s[i]] <= priority[opt.top()])
{
int num2 = num.top();
num.pop();
int num1 = num.top();
num.pop();
char c = opt.top();
opt.pop();
int res = cal(num1, num2, c);
num.push(res);
}
opt.push(s[i]);
}
i++;
}
}
while(!opt.empty() && !num.empty())
{
int num2 = num.top();
num.pop();
int num1 = num.top();
num.pop();
char c = opt.top();
opt.pop();
int res = cal(num1, num2, c);
num.push(res);
}
return num.top();
}
};
再贴一种代码 思路和上述我的思路一样,但是代码风格更好看一点:
class Solution {
public:
bool cmp(char op1, char op2){
if((op1 == '+' || op1 == '-') && (op2 == '*' || op2 == '/')){
return false;
}else if(op1 == '#'){
return false;
}else if(op2 == '#'){
return true;
}else{
return true;
}
}
int cal(int a, int b, int op){
switch (op){
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b;
default: return 0;
}
}
int calculate(string s) {
int ans = 0;
int index = 0;
s += "#";
int len = s.length();
stack<int> num;
stack<char> opt;
opt.push('#');
while(index < len){
while(index < len && s[index] == ' '){
++index;
}
if(index < len && s[index] >= '0' && s[index] <= '9'){
int tmp = 0;
while(index < len && s[index] >= '0' && s[index] <= '9'){
tmp = tmp * 10 + s[index] - '0';
++index;
}
num.push(tmp);
//cout<<"push: "<<tmp<<endl;
}else if(index < len){
char c = s[index++];
//cout << "top "<<opt.top()<<" c "<<c<<endl;
while(!opt.empty() && cmp(opt.top(), c)){
int b = num.top();
num.pop();
int a = num.top();
num.pop();
num.push(cal(a, b, opt.top()));
//cout<<"push calc: "<<cal(a, b, opt.top())<<endl;
opt.pop();
}
//cout<<"push: "<<c<<endl;
opt.push(c);
}
}
return num.top();
}
};