HDU 1237 简单计算器 表达式求值 数据结构

HDU 1237 简单计算器(模拟) - 博客频道 - CSDN.NET
简单点,Coding的方式简单点
分类:HDU模拟
Description
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位
Sample Input
4 + 2 * 5 - 7 / 11
Sample Output
模拟四则运算过程,对于整个输入的串,遇到数字则提取出来进数字栈,遇到加减运算则进运算符栈,遇到乘除运算则从数字栈中拿出栈顶元素与运算符之后提取出的整数进行运算并将结果进数字栈,这样当枚举完整个串的元素后,我们就得到了一个只有加减运算的表达式,但因为这个表达式在栈中的顺序是反的,所以要再开两个栈来将这个表达式反序,之后就每次从数字栈栈顶取出两元素,从运算符栈中取出一个运算符,将运算结果压进数字栈中,最后数字栈剩下的一个元素即为表达式的最终结果
#include&cstdio&
#include&cstring&
#include&iostream&
#include&stack&
using namespace std;
int main()
char s[222];
while(gets(s),strcmp(s,"0"))
int len=strlen(s);
stack&double&
stack&char&
for(int i=0;i&i++)
if(s[i]==' ')
else if(s[i]=='*'||s[i]=='/')
double x=num.top();
num.pop();
double y=0;
for(j=i+2;j&j++)
if(s[j]!=' ')
y=y*10+s[j]-'0';
if(s[i]=='*')
num.push(x*y);
num.push(x/y);
else if(s[i]=='+'||s[i]=='-')
op.push(s[i]);
double y=0;
for(j=i;j&j++)
if(s[j]!=' ')
y=y*10+s[j]-'0';
num.push(y);
stack&double&
stack&char&
while(!num.empty())
double temp=num.top();
nnum.push(temp);
num.pop();
while(!op.empty())
char temp=op.top();
oop.push(temp);
while(!nnum.empty()&&!oop.empty())
double x=nnum.top();
nnum.pop();
double y=nnum.top();
nnum.pop();
char ope=oop.top();
oop.pop();
if(ope=='+')
nnum.push(x+y);
nnum.push(x-y);
printf("%.2lf\n",nnum.top());
排名:千里之外
(467)(535)(299)(186)(8)(3)(2)(4)(4)(1)(49)(4)(34)(23)(2)(1)(424)(84)(91)(54)(10)(12)(19)(17)(20)(57)(56)(123)(10)(9)(5)(1)(1)(28)(12)(49)(26)(30)(15)(11)(4)(9)(86)(10)(3)(2)(13)(22)(23)(14)(14)(6)(1)(11)(14)(6)(19)(6)(34)(31)(8)(8)(3)(20)(1)(1)(2)(14)(8)(5)(5)(129)(16)(9)(5)HDU 1237 简单计算器 表达式求值 - 博客频道 - CSDN.NET
小人物_cipher
笔记本随便记记而已 莫当真
分类:ACM steps
简单计算器
Time Limit:
MS (Java/Others)&&&&Memory Limit:
K (Java/Others)
Total Submission(s): 12466&&&&Accepted Submission(s): 4098
Problem Description
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
Sample Input
4 + 2 * 5 - 7 / 11
Sample Output
HDU 1237 表达式求值
现将下表达式求值的思想:
1.将中缀表达式转为后缀表达式
设置两个栈,一个用来保存后缀式的栈,一个用来暂时保存运算符的栈,
将中序表达式一个一个字符地读入,遇到数字字符就直接压入后缀式栈,
遇到运算符时就先暂时保存到运算符栈中,
等到下次读到字符时将运算符栈中的运算符与之比较优先级,
若运算符栈里的运算符的优先级高于这次读到的运算符就将运算符栈中的运算符进栈,
否则将这个运算符压入运算符栈。
4 + 2 * 5 - 7 / 11
425*711/-+
2.后缀表达式求值
遇到字符是个操作符,弹出2个操作数,运算完结果压入
或者运算符栈里的优先级高 直接弹出2个数计算 后再压入
==&*计算 +计算
#include&iostream&
#include&stdio.h&
#include&stack&
#include&cstring&
char str[205];
int change(char c)
if(c=='+')
if(c=='-')
if(c=='*')
if(c=='/')
return -1;
int cmp(int a,int b)
if(a==1||a==2)
if(b==1||b==2)
void cal()
stack&double&a;
//后缀结果栈
stack&int&b; // 运算符栈
int i,len=strlen(str);
for(i=0;i&i++)
if(str[i]==' ')
if(str[i]&='0'&&str[i]&='9') //数字
while(str[i]&='0'&&str[i]&='9')
s=s*10+str[i]-'0';
a.push(s);
if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/')
temp=change(str[i]);
if(b.empty())
b.push(temp);
int t=b.top();//运算符栈里的优先级大于当前的,将运算符栈里的压入到后缀
while(cmp(t,temp))
double a1=a.top(); a.pop();
//弹出2个操作数
double b1=a.top(); a.pop();
int c=b.top(); b.pop();//弹出运算符栈里的运算符
a.push(a1+b1);
a.push(b1-a1);
a.push(a1*b1);
a.push(b1/a1);
if(b.empty()) //如果这样写要判断为空否
//否则继续比较运算符栈顶运算
t=b.top();
b.push(temp); // 将这个运算符压入运算符栈
while(!b.empty())
double a1=a.top(); a.pop();
//弹出2个操作数
double b1=a.top(); a.pop();
int c=b.top(); b.pop();//弹出运算符栈里的运算符
a.push(a1+b1);
a.push(b1-a1);
a.push(a1*b1);
a.push(b1/a1);
printf(&%.2lf\n&,a.top());
int main()
while(gets(str),strcmp(str,&0&))
排名:千里之外
(220)(199)(19)(296)(0)(6)(6)(37)(10)(1)(189)(1)(37)(2)(80)(2)(73)(22)(3)(1)(13)Theory and practice(7)
Java Study(9)
这个东西一直是大家关注的热点,也是这个题目的真正目标所在,希望大家能够好好学习了解这个部分的思路想法。虽然这个思路不是以后编译原理上面的标准思路,也不是什么正统方法,但是它确实符合大家的想法和一贯的思路。因为不够正统和强悍,如有高人敬请指点。那么我们来考虑一下这个表达式,如果只有加减运算符大家是否感觉能很好的解决呢?首先是单位的数字和运算符(只有加减),那么我们就只用顺序处理即可。形如:a+b-c+d,我们是如何计算的呢?首先计算a+b,然后将结果e替代a+b--&e-c+d--&h+d--&i一次一次计算替换的反复。如此以来我们就有了一个思路,拿出三个,计算结果丢进去,再拿出三个计算。我们假设,这个表达式已经切割好了,放在一个栈(第二步有讲)里面,我们通过对栈操作实现全部运算。
first&:=&pop()while&&&&stack&is&not&empty&&&&do&&&&&&&operator&:=&pop()&&&&&&&&&&&&&&&second&&&&:=&pop()&&&&&&&&&&&&&&&res&&&&&&&&&&&&:=&&first&&&&operator&&&second&&&&&&&&&&&&&&&push(res)&&&&&&&&&&&&&&&first&&&&&&&&&&:=&&pop()return&first
以上的计算是基于:运算符优先级一样,格式正确。剩下的就是来切割解析这个表达式使之成为这种结构。我们只需要一直解析这个字符串,如果出现,标点则前面的就是一个数,我们将它压入栈中。就是类似的方法喽。
p:=&&n:=1while&&&n&=length[expression]&&&&&&&&do&&&&&if&&&expression[n]&is&the&operator&&&&&&&&&&&&&&&&&&&&&&&then&&&&&if&&&not&&&p=&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&then&&&push(p)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& p=&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&push(expression[n])&&&&&&&&&&&&&&&&&&&&&&&else&&&&&&p:=p+expression[n]&&&&&&&&&&&&&&&&&n:=n+1return&stack
好了,我们现在是同优先级的没有问题了,如果有高优先级的怎么办呢?如果只考虑+-*/那么只要是*/号出现就可以对其操作符左右的数据进行运算了。也就是说在上面的伪代码里面我们需要加一步判断operator是否为*/的情况,然后进行运算。但是如果我们只扫描到operator就要运算,对于一个双目运算符来说还差一边啊,那么我们能否将这个判断推迟到压入数字的时候进行呢?这样我们需要在压入数据的时候提出前面的若干项进行处理了。
p:=&&n:=1while&&&n&=length[expression]&&&&&&&&do&&&&&if&&&expression[n]&is&the&operator&&&&&&&&&&&&&&&&&&&&&&&then&&&&&if&&&not&&&p=&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&then&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//Be&careful&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&operator&:=&pop()&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if&&&&operator&is&the&*&&or&/&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&then&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&first&:=&pop()&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&second&:=p&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&p:=&first&&operator&&second&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&push(p)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&p=&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&push(expression[n])&&&&&&&&&&&&&&&&&&&&&&&else&&&&&&p:=p+expression[n]&&&&&&&&&&&&&&&&&n:=n+1return&stack
如此以来我们实现了+-*/了,HOHO 不错吧,思路就是这样一步一步来的。下面我们想加入括号了,现在我们继续想,其实括号就是更高的一层优先级了,由于基于以上的运算处理,在括号&缝合&(即碰到了')')的时候括号里面只有加减法,也就是说刚刚的栈处理结束标志是表达式末尾开始的标志就是表达式开头,而这里的开头是&(&结尾是&)&,还有什么区别吗?其实没什么了,那么我们按照这个思路,如果expression[n]是括号,&(&压入栈中,')'开始运算将结果压入栈中。这样看似乎不难哦。
p:=&&n:=1while&&&n&=length[expression]&&&&&&&&do&&&&&if&&&expression[n]&is&the&operator&&&&&&&&&&&&&&&&&&&&&&&then&&&&&if&&&not&&&p=&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&then&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//Be&careful&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&operator&:=&pop()&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if&&&&operator&is&the&*&&or&/&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&then&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&first&:=&pop()&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&second&:=p&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&p:=&first&&operator&&second&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&push(p)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&p=&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&push(expression[n])&&&&&&&&&&&&&&&&&&&&&&&elseif&&&expression[n]&is&the&bracket&(&or&)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&then&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if&&expression[n]=&(&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&then&push(expression[n])&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&else& res:=compute&the&expression&between&the&&(&&and&&)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //Push the result& & & & & & & & & & & & & & & & & & & & & & & & & & & && push(res) &&&& &&&&&&&&&&&&&&&&&&&&&&&else&&&&&&p:=p+expression[n]&&&&&&&&&&&&&&&&&n:=n+1return&stack
这样看似乎很爽啊,但是大家看看这个表达式& 1+(2+3*4)*(5+6)计算结果是 165& 而不是正确结果 155.为什么呢?因为我们在计算之后直接压入栈中而忽略了前面的那个*号。至此我们应该知道,一旦压入数据就得检查前面的operator.这样以来我们需要对push(object)单独再包装一下,使它明白只要压入就得检查.至此我们已经知道了基本的运算体系。在实际编码过程中,大家可能要碰到大量的边界讨论问题,这一定要小心。关于乘方和小数问题我将尽快写出来。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:41109次
排名:千里之外
原创:23篇
转载:14篇
(2)(6)(7)(2)(2)(2)(1)(4)(6)(5)1319人阅读
Problem Description
Sample Input
Sample Output
这道题 我竟无言以对。。
其实也就是模拟计算器。因为这里没有小括号 很简单。只需要判断当前运算符和下一个运算符的优先级
就行,分别用两个栈存贮数字和符号,我用的数组。
我就是因为一个数据不对 而且我也找不出来。。浪费了N多时间。
有几个注意的地方
1:如果输入的第一个数字是0 例如0 + 2 + 3应该输出5.00 而不是结束
2:如果输入的是0(空格)(换行)应该输出0.00(我错在了这里。。气死了)
3. & 数字可能是两位及两位以上
最后换换输入方式 就对了。附上wa和ac的代码
#include &stdio.h&
#include &string.h&
int main()
char fuhao[100],str[205];
double num[100],
while(gets(str)&&strcmp(str,&0&)!=0)
int len=strlen(str);
int t=0,q=0;
memset(num,0,sizeof(num));
memset(fuhao,0,sizeof(fuhao));
for(int i=0;i&i++)
if(str[i]&='0'&&str[i]&='9')
double temp=0;
while(str[i]&='0'&&str[i]&='9')
temp=temp*10+str[i]-'0',i++;
if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/')
fuhao[t++]=str[i];
memset(str,0,sizeof(str));
sum=num[0];
for(int i=1;i&q;i++)
num[i-1]=num[i];
for(int i=0;i&t;i++)
if(fuhao[i]=='*')
sum=sum*num[i];
else if(fuhao[i]=='/')
sum=sum/num[i];
else if(fuhao[i]=='+')
if(fuhao[i+1]=='*'||fuhao[i+1]=='/'&&i+1&t)
double temp=num[i];
while((fuhao[i+1]=='*'||fuhao[i+1]=='/')&&i+1&t)
if(fuhao[i+1]=='*')
temp=temp*num[i+1];
temp=temp/num[i+1];
sum=sum+num[i];
else if(fuhao[i]=='-')
if(fuhao[i+1]=='*'||fuhao[i+1]=='/'&&i+1&t)
double temp=num[i];
while((fuhao[i+1]=='*'||fuhao[i+1]=='/')&&i+1&t)
if(fuhao[i+1]=='*')
temp=temp*num[i+1];
temp=temp/num[i+1];
sum=sum-num[i];
printf(&%.2lf\n&,sum);
wa的,就是输入的地方不一样
#include &stdio.h&
#include &string.h&
int main()
char fuhao[200];
double num[200],
while(scanf(&%lf&,&sum)!=EOF)
char mark=getchar();
if(mark=='\n'&&sum==0)
printf(&%.2lf\n&,sum);
memset(fuhao,0,sizeof(fuhao));
memset(num,0,sizeof(num));
scanf(&%c&,&fuhao[t]);
scanf(&%lf&,&num[t]);
mark=getchar();
if(mark=='\n')
for(int i=0;i&=t;i++)
if(fuhao[i]=='*')
sum=sum*num[i];
else if(fuhao[i]=='/')
sum=sum/num[i];
else if(fuhao[i]=='+')
if(fuhao[i+1]=='*'||fuhao[i+1]=='/')
double temp=num[i];
while((fuhao[i+1]=='*'||fuhao[i+1]=='/')&&i+1&=t)
if(fuhao[i+1]=='*')
temp=temp*num[i+1];
temp=temp/num[i+1];
sum=sum+num[i];
else if(fuhao[i]=='-')
if(fuhao[i+1]=='*'||fuhao[i+1]=='/')
double temp=num[i];
while((fuhao[i+1]=='*'||fuhao[i+1]=='/')&&i+1&=t)
if(fuhao[i+1]=='*')
temp=temp*num[i+1];
temp=temp/num[i+1];
sum=sum-num[i];
printf(&%.2lf\n&,sum);
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1182712次
积分:18608
积分:18608
排名:千里之外
原创:591篇
转载:17篇
评论:313条
点图片联系我
点图片联系我
文章:49篇
阅读:116414
文章:234篇
阅读:506909
文章:123篇
阅读:267973
文章:16篇
阅读:20605
(5)(5)(17)(52)(17)(4)(6)(10)(19)(36)(17)(63)(30)(16)(46)(11)(14)(10)(22)(16)(58)(52)(3)(18)(37)(23)(1)我用栈写,一个栈保存符号,一个栈保存数字。
有个技巧是再添加一个结束符'#'.然后根据优先级来进行计算即可。
如果有括号的话再加一个优先级比较的数组即可。
至于优先级,首先是普通认知的优先级,然后相同优先级前者的大于后者。
左括号小于任何,又括号大于任何。
#include &iostream&
#include &vector&
#include &stack&
#include &cstring&
#include &cstdio&
stack&double& OPN;//restore the num
stack&char& OPO;//restore the operation
1 is prior
0 is equal
-1 is lower
int op[200][200];
void init(){
while(!OPN.empty())
OPN.pop();
while(!OPO.empty())
OPO.pop();
OPO.push('#');
op['+']['+']=1;op['+']['-']=1;op['+']['*']=-1;op['+']['/']=-1;
op['-']['+']=1;op['-']['-']=1;op['-']['*']=-1;op['-']['/']=-1;
op['*']['+']=1;op['*']['-']=1;op['*']['*']=1; op['*']['/']=1;
op['/']['+']=1;op['/']['-']=1;op['/']['*']=1; op['/']['/']=1;
op['+']['#']=1;op['-']['#']=1;op['*']['#']=1; op['/']['#']=1;
op['#']['+']=-1;op['#']['-']=-1;op['#']['*']=-1; op['#']['/']=-1;
bool in(char c){
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='#'||c==' ')
double operate(double s1,double s2,char opp){
switch(opp){
case '+':
return s1+s2;
return s1-s2;
return s1*s2;
return s1/s2;
int main(){
char str[250];
while(gets(str)){
double s=0;
int len=strlen(str);
if(str[0]=='0'&&len==1)
str[len]='#';
str[len+1]='\0';
// puts(str);
while(str[i]!='#'||OPO.top()!='#'){
if(str[i]==' ') { i++;}
while(!in(str[i])){
s=s*10+(str[i]-'0');
//printf(&%lf\n&,s);
i++;
OPN.push(s);
char t_op=OPO.top();
if(op[(int)t_op][(int)str[i]]==1){
double _s=OPN.top();
OPN.pop();
double s_=OPN.top();
OPN.pop();
// printf(&%lf %lf \n&,_s,s_);
double temp=operate(s_,_s,t_op);
OPN.push(temp);
OPO.pop();
OPO.push(str[i]);
else if(op[(int)t_op][(int)str[i]]==-1){
OPO.push(str[i]);
i++;
double ans=OPN.top();
printf(&%.2lf\n&,ans);
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场}

我要回帖

更多关于 c语言算术表达式求值 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信