hdu 1237简单计算器

6 篇文章 0 订阅

题目描述

Problem Description

读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。

Input

测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。

Output

对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。

Sample Input

1 + 2
4 + 2 * 5 - 7 / 11
0

Sample Output

3.00
13.36
 
解题思路:   此题是典型的栈的例题,运用到了用栈来实现中缀表达式转化成后缀表达式及其求解的方法,
中缀表达式转化成后缀表达式的方法:
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈
6.最终将栈中的元素依次出栈,输出。
 
后缀表达式的计算:  从左到右扫描后缀表 达式,遇到运算符就把表达式中该运算符前面两个操作数取出并运算,然后把结果带回后缀表达式;继续扫描直到后缀表达式最后一个表达式。
 
本题还需注意空格的入栈
代码如下:
#include<stdio.h>
#include<string.h>
#include<stack>
#include<algorithm>
using namespace std;
char s[300],suffix[1000];
int fuhao(char ch)//各个符号的优先级
{
    switch(ch)
    {
        case '#':return 0;
        case '+':return 1;
        case '-':return 1;
        case '*':return 2;
        case '/':return 2;
    }
    return -1;
}
int is_num(char ch)//是不是数字
{
    if(ch>='0'&&ch<='9')
       return 1;
    return 0;
}
void Transform(char *suffix,char *s)//转换成后缀式
{
    stack<char>op;
    int l=strlen(s),i,k=0;
    op.push('#');
    for(i=0;i<l;i++)
    {
        if(is_num(s[i])||s[i]==' ')   //数字或空格 存入数组 
             suffix[k++]=s[i];
        else
        {
            while(!op.empty()&&fuhao(op.top())>=fuhao(s[i]))//将stack中的所有的优先级不小于当前操作符的优先级的操作符发送给后缀式
            {
                suffix[k++]=op.top();  //栈顶取出放入数组 
                op.pop();   //出栈 
            }
            if(s[i]!='#')  op.push(s[i]);
        }
    }
    suffix[k]='\0';
}
void Calculate()
{
    stack<double>ans;
    int i=0,l=strlen(suffix);
    while(i<l)
    {
        if(suffix[i]==' ')
        {
            i++;continue;
        }
        if(suffix[i]=='#')  break;
        else
        {
            double a=0;
            int flag=0;
            while(is_num(suffix[i]))    //是否为数字 
            {
                a*=10;
                a+=(suffix[i++]-'0');
                flag=1;
            }
            if(flag)
            ans.push(a);
            if(suffix[i]==' ')  {i++;continue;}//不要写成if(suffix[i++]=' ')
            if(fuhao(suffix[i])>0)
            {
                double num1,num2,num3;
                num1=ans.top();
                ans.pop();//注意弹出。
                num2=ans.top();
                ans.pop();
                switch(suffix[i++])
                {
                    case '+':num3=num2+num1;break;
                    case '-':num3=num2-num1;break;
                    case '*':num3=num2*num1;break;
                    case '/':num3=num2/num1;break;
                }
                ans.push(num3);
            }
        }
    }
    printf("%.2lf\n",ans.top());
}
int main()
{
    while(gets(s))//注意用gets,因为有空格,不要用scanf
    {
        memset(suffix,NULL,sizeof(suffix));
        int l=strlen(s);
        if(l==1&&s[0]=='0')
        break;
        else
        {
            s[l]='#';//加个#,作为结束标志
            Transform(suffix,s);
           Calculate();
        }
    }
    return 0;
}

 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值