问题描述:
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
Note: Do not use the eval built-in library function.
实现一个简易计算器,计算简单表达式字符串的值。
表达式字符串只包含非负整数, +, -, *, / 运算和空白字符。整数除法的得数舍去小数部分。不要使用内置的库函数eval。
问题求解:
方法一:大概思路:以’+’或者’-‘作为分割点,将输入字符串分割成若干部分,每一部分的值由一个叫tmpnum的数来存储,总数total即是各部分tmpnum值相加的和。
例如输入”1 +2 * 4-5/3”,则将被划分成三部分:(+)1, (+)2 * 4, (-)5/3。
class Solution {
public:
int calculate(string s) {
int n=s.size();
int i=0;
int curnum, total=0, tmpnum=0;
char op='+';//第一个数字前的op初始化为'+'
while(i<n)
{
if(isdigit(s[i]))
{//(1)如果当前s[i]是数字
curnum=0;
while(i<n && isdigit(s[i]))
{//(1.1)出现连续数字则按十进制求值并记为curnum
curnum = curnum*10+(s[i]-'0');
i++;//操作完之后i已经到了下一个地方!!!
}
//(1.2)检查curnum前的操作符,以更新当前tmpnum结果
if(op=='+' || op=='-')
{//(1.2.1)若op为'+'或'-',即到了分割点,当前的tmpnum停止计算,将其加入到total
// 然后更新tmpnum,以便下一次计算
total += tmpnum;
tmpnum = curnum*(op=='+'?1:-1);
}
//(1.2,2)若op为'*'或'/',接着计算tmpnum
else if(op=='*')
{
tmpnum *= curnum;
}
else if(op=='/')
{
tmpnum /= curnum;
}
}
//(2)如果是空格,则略过,扫描下一个
else if(s[i]==' '){i++;continue;}
else {op=s[i];i++;}//(3)如果是操作符,则更新op,并扫描下一个
}
total += tmpnum;//(4)total加上最后一个tmpnum
return total;
}
};
方法二:使用栈。直接对给出的中缀表达式进行处理。首先在给定的表达式前面设置一个’+’运算符。对于每个操作数而言,看其前面的操作符:
(1)如果是’+’:操作数tmp直接入栈
(2)如果是’-‘:操作数tmp加符号后入栈,即-tmp入栈
(3)如果是’*’:弹出栈顶元素,与tmp相乘后的乘积入栈。即:
num = myStack.top()*tmp;
myStack.pop();
myStack.push(num);
(4)如果是’/’:弹出栈顶元素,与tmp相除后的商入栈。即:
num = myStack.top()/tmp;
myStack.pop();
myStack.push(num);
最后将栈里的元素逐个相加即可。
class Solution {
public:
int calculate(string s) {
stack<int> Mystack;
int res=0, tmp=0;
//(1)op初始化为'+'
char op='+';
for(unsigned int i=0;i<s.size();i++)
{
if(isdigit(s[i]))
{//(2)得到操作数tmp
tmp = tmp*10+(s[i]-'0');
}
if(!isdigit(s[i]) && !isspace(s[i]) || i==s.size()-1)
{//(3)一个操作数tmp拿取结束,操作符op或者到结尾.开始检验前面的op.
//(3.1)之前的op是'+',直接入栈
if(op=='+') Mystack.push(tmp);
//(3.2)之前的op是'-',-tmp入栈
else if(op=='-') Mystack.push(-tmp);
else{
int num=0;
if(op=='*')
{//(3.3)之前的op是'*',栈顶与tmp乘积入栈
num=Mystack.top()*tmp;
}
if(op=='/')
{//(3.4)之前的op是'/',栈顶与tmp商入栈
num=Mystack.top()/tmp;
}
Mystack.pop();
Mystack.push(num);
}
//(3.5)用此次遇到的操作符更新op,操作数置为0
op=s[i];
tmp=0;
}
}
while(!Mystack.empty())
{//(4)依次将栈里元素相加
res += Mystack.top();
Mystack.pop();
}
return res;
}
};