实现基础计算器--Basic Calculator
2015-10-20 19:52
211 查看
题目:
BasicCalculator:
Implementabasiccalculatortoevaluateasimpleexpressionstring.
Theexpressionstringmaycontainopen
思考:
1、首先分析题意,题目要求计算表达式值,首先想到的就是使用栈存储表达式,可先通过处理运算符将原表达式转化为后缀式,进而通过优先级计算后缀式,得到结果
2、但是仔细分析,可以发现,本题不需要将原式转化为后缀式求解。表达式中只包含非负整数,括号,+,-,以及空格。并不存在运算优先级的问题,只需要处理括号即可。
具体思路:
建立两个栈,分别为char,int,存储表达式中的运算符,和数字。用字符串s存储表达式,s尾部添加'#',表示结束,从头开始扫描s[i]:
s[i]为'',不作操作。
s[i]为'(',进栈。
s[i]为'+','-',判断运算符栈顶是否为空,或是否为'(',若不是则将数字栈的前两个元素弹出,将运算符栈弹出,进行运算,运算结果入栈,s[i]入栈。
s[i]为')',将'('前的运算符弹出计算。
s[i]为数字,将下一个运算符前的数字一同计算,结果压入栈。
s[i]为'#',判断运算符栈是否为空,不为空,再弹栈进行计算,得到结果。
代码:
进一步思考,当s结束时,需要再次判断数字栈是否为空,较为麻烦,可以在运算符栈先压入'(',且在字符串s后加')',则当s[i]为最后的')'时,可将运算符栈最底端'('之前的运算符都弹出计算,代码更加清晰简短。
代码如下:
总结:
这个题目较为简单,只包含'+','-','','(',')',无需求后缀式,可简化程序。此算法只进行了一次扫描,时间复杂度为o(n),使用两个栈存储,空间复杂度为o(n),但此方法缺点是可扩展性较差,只适用于这个题目。
此博客中的内容均为原创或来自网络,不用做任何商业用途。欢迎与我交流学习,我的邮箱是lsa0924@163.com
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
相关文章推荐
- 使用secureCrt端口转发连接远程服务器mysql
- Minimum Depth of Binary Tree
- Android第三方开源ImageLoader的使用(一)
- 设计模式之一 设计模式概述
- 爬爬爬之路:C语言(九) 结构体指针与预编译指令
- Java 8.1
- c++数组访问越界的问题
- jquery的ajax
- ios开发之c语言基础-结构体
- android 随机云标签(圆形)
- 内存映射文件 进程间通讯
- DELPHI 让子窗体显示在任务栏上
- HBase深入学习笔记
- 参加某项目例会小记-2015-10-20
- 如何访问到静态的文件,如jpg,js,css?
- MySQL数据库高并发优化配置
- Android studio通过JNI调用动态链接库SO
- 图形的几何变换(平移,比例,定点比例)
- 将 nginx 安装成 windows 的方法
- 【软剑攻城队】用户需求分析文档发布!