您的位置:首页 > 其它

实现基础计算器--Basic Calculator

2015-10-20 19:52 211 查看
题目:

BasicCalculator:

Implementabasiccalculatortoevaluateasimpleexpressionstring.

Theexpressionstringmaycontainopen
(
andclosingparentheses
)
,theplus
+
orminussign
-
,non-negativeintegersandemptyspaces
.

思考:

  1、首先分析题意,题目要求计算表达式值,首先想到的就是使用栈存储表达式,可先通过处理运算符将原表达式转化为后缀式,进而通过优先级计算后缀式,得到结果

  2、但是仔细分析,可以发现,本题不需要将原式转化为后缀式求解。表达式中只包含非负整数,括号,+,-,以及空格。并不存在运算优先级的问题,只需要处理括号即可。

具体思路:

  建立两个栈,分别为char,int,存储表达式中的运算符,和数字。用字符串s存储表达式,s尾部添加'#',表示结束,从头开始扫描s[i]:

s[i]为'',不作操作。

s[i]为'(',进栈。

s[i]为'+','-',判断运算符栈顶是否为空,或是否为'(',若不是则将数字栈的前两个元素弹出,将运算符栈弹出,进行运算,运算结果入栈,s[i]入栈。

s[i]为')',将'('前的运算符弹出计算。

s[i]为数字,将下一个运算符前的数字一同计算,结果压入栈。

s[i]为'#',判断运算符栈是否为空,不为空,再弹栈进行计算,得到结果。

代码:

#include<iostream>
#include<stack>
#include<string>
usingnamespacestd;

classSolution
{
public:
intcalculate(strings)
{
stack<int>numbers;
stack<char>ops;
s.push_back('#');//插入终止符'#'
for(inti=0;i<s.length();i++)//依次扫描字符串s
{
switch(s[i])
{
case'':
break;
case'(':
ops.push(s[i]);
break;
case')':
while(ops.top()!='(')
{
intnum_1,num_2;
chartemp_op;
num_2=numbers.top();
numbers.pop();
num_1=numbers.top();
numbers.pop();
temp_op=ops.top();
ops.pop();
numbers.push(calculating(num_1,num_2,temp_op));
}
ops.pop();
break;
case'#':
if(!ops.empty())
{
intnum_1,num_2;
chartemp_op;
num_2=numbers.top();
numbers.pop();
num_1=numbers.top();
numbers.pop();
temp_op=ops.top();
ops.pop();
numbers.push(calculating(num_1,num_2,temp_op));
};
break;
case'+':
case'-':
if(!ops.empty())
{
if(ops.top()!='(')
{
intnum_1,num_2;
chartemp_op;
num_2=numbers.top();
numbers.pop();
num_1=numbers.top();
numbers.pop();
temp_op=ops.top();
ops.pop();
numbers.push(calculating(num_1,num_2,temp_op));
}
}
ops.push(s[i]);
break;
default://处理s[i]为数字的情况
inttemp_answer=s[i]-'0';
while(isDigit(s[i+1]))
{
temp_answer=temp_answer*10+s[++i]-'0';
}
numbers.push(temp_answer);
break;
}
}
returnnumbers.top();
}
boolisDigit(chara)//判断字符是否为'0'-'9'
{
if(a>='0'&&a<='9')
{
returntrue;
}
else
{
returnfalse;
}
}
intcalculating(intnum1,intnum2,charop)//加减计算
{
switch(op)
{
case'+':
returnnum1+num2;
break;
default:
returnnum1-num2;
break;
}
}
};

intmain()
{
Solutionsolution;
strings;
cin>>s;
cout<<solution.calculate(s)<<endl;
return0;
}


进一步思考,当s结束时,需要再次判断数字栈是否为空,较为麻烦,可以在运算符栈先压入'(',且在字符串s后加')',则当s[i]为最后的')'时,可将运算符栈最底端'('之前的运算符都弹出计算,代码更加清晰简短。

代码如下:

#include<iostream>
#include<stack>
#include<string>
usingnamespacestd;

classSolution
{
public:
intcalculate(strings)
{
stack<int>numbers;
stack<char>ops;
ops.push('(');
s.push_back(')');
for(inti=0;i<s.length();i++)
{
switch(s[i])
{
case'':
break;
case'(':
ops.push(s[i]);
break;
case')':
while(ops.top()!='(')
{
intnum_1,num_2;
chartemp_op;
num_2=numbers.top();
numbers.pop();
num_1=numbers.top();
numbers.pop();
temp_op=ops.top();
ops.pop();
numbers.push(calculating(num_1,num_2,temp_op));
}
ops.pop();
break;
case'+':
case'-':
if(!ops.empty()&&ops.top()!='(')
{
intnum_1,num_2;
chartemp_op;
num_2=numbers.top();
numbers.pop();
num_1=numbers.top();
numbers.pop();
temp_op=ops.top();
ops.pop();
numbers.push(calculating(num_1,num_2,temp_op));
}
ops.push(s[i]);
break;
default:
inttemp_answer=s[i]-'0';
while(isDigit(s[i+1]))
{
temp_answer=temp_answer*10+s[++i]-'0';
}
numbers.push(temp_answer);
break;
}
}
returnnumbers.top();
}
boolisDigit(chara)
{
if(a>='0'&&a<='9')
{
returntrue;
}
else
{
returnfalse;
}
}
intcalculating(intnum1,intnum2,charop)
{
switch(op)
{
case'+':
returnnum1+num2;
break;
default:
returnnum1-num2;
break;
}
}
};

intmain()
{
Solutionsolution;
strings;
cin>>s;
cout<<solution.calculate(s)<<endl;
return0;
}


总结:

  这个题目较为简单,只包含'+','-','','(',')',无需求后缀式,可简化程序。此算法只进行了一次扫描,时间复杂度为o(n),使用两个栈存储,空间复杂度为o(n),但此方法缺点是可扩展性较差,只适用于这个题目。

此博客中的内容均为原创或来自网络,不用做任何商业用途。欢迎与我交流学习,我的邮箱是lsa0924@163.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: