HDU-1237 简单计算器 解题报告

HDU - 1237

题目描述

简单计算器

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

Input

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

Output

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

Sample Input

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

Sample Output

3.00
13.36

在这里我简单地修改题目,允许使用括号,也允许小数输入,之后的代码也支持这个功能,原题AC代码可以自行修改

题目大意

中文题目不用解释,在这个修改中,加入了括号的使用,在判断时要加上对括号的判断,在读取数字时,要额外考虑小数点的状况。此外,表达式中没有空格,这就意味着一次性输入,这不同于逆波兰表达式求值的一些内容。

解题方法

使用递归的方法。
我们逐层分析

扫描二维码关注公众号,回复: 3099832 查看本文章
  • 表达式expression,它由若干个项term组成,每个项之间用’+’或者’-‘连接。
  • 项term,它由若干个因子factor组成,每个因子之间用’*’或者’/’连接。
  • 因子factor,它由一个数字或者一个()括号表达式组成,在这里我们看到了递归,括号表达式即为一个递归条件,它的终止条件是因子是一个数。

因此我们需要这么几个函数:experssion_value(),term_value(),factor_value()。用他们分别计算表达式的值,项的值以及因子的值。其中,用expression_value()调用term_value(),term_value()调用factor_value(),factor_value()达到终止条件或者递归调用experssion_value()。总之,中间有个层级关系,要捋清递归关系。
另外一个问题,要对字符串进行操作,这里用到的方法使用cin.peek()和cin.get()进行读取和读出。其中,cin.peek()会返回输入流中的第一个字符,但不会删除,cin.get()同样返回输入流中的第一个字符,但是会删除。这样就方便了我们对字符串进行操作,只需要查看第一个字符的类型,就可以知道表达式中的运算关系。

举个例子:
表达式3.4+2*(6*4+1/5)
调用experssion_value()计算表达式的值,进入函数,用term_value()计算第一个项的值,进入term_value()函数,用factor_value()计算第一因子的表达式,cin.peek()发现第一个字符为3,则循环读取3.4,返回term_value(),没有其他因子,返回experssion_value(),存入结果result,cin.peek()读取到’+’,调用term计算第二项的值,同理,计算返回后,与rusult相加,得到答案。

另外,从字符串读取一个小数的代码如下:

#include <iostream>
#include <cstdio>
#include <cctype>
#include <cmath>
using namespace std;
int main()
{
    int dot = 0;
    double result = 0;
    char op;
    op = cin.peek();
    while(isdigit(op) || op == '.')      //isdigit()为cctype中的函数,用于判断一个数是否为十进制数字
    {
        if(op == '.')
        {
            dot = -1;
            cin.get();
            op = cin.peek();
        }
        else
        {
            if(dot == 0)
            {
                cin.get();
                result = 10 * result + op - '0';
                op = cin.peek();
            }
            else
            {
                cin.get();
                result += pow(10, dot) * (op - '0');
                dot --;
                op = cin.peek();
            }
        }
    }
    printf("%.2f\n", result);
    return 0;
}

以下为题解代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <algorithm>
using namespace std;
float factor_value();
float term_value();
float expression_value();
int main()
{
    printf("%.2f\n", expression_value());
    return 0;
}
float expression_value()
{
    float result = term_value();
    bool more = true;
    while(more)
    {
        char op = cin.peek();
        if(op == '+' || op == '-')
        {
            cin.get();
            float value = term_value();
            if(op == '+')
                result += value;
            else
                result -= value;
            op = cin.peek();
        }
        else
            more = false;
    }
    return result;
}
float term_value()
{
    float result = factor_value();
    bool more = true;
    while(more)
    {
        char op = cin.peek();
        if(op == '*' || op == '/')
        {
            cin.get();
            float value = factor_value();
            if(op == '*')
                result *= value;
            else
                result /= value;
            op = cin.peek();
        }
        else
            more = false;
    }
    return result;
}
float factor_value()
{
    float result = 0;
    char op = cin.peek();
    if(op == '(')
    {
        cin.get();
        result = expression_value();
        cin.get();
    }
    else
    {
        int dot = 0;
        while(isdigit(op) || op == '.')
        {
            cin.get();
            if(op == '.')
            {
                dot = -1;
                op = cin.peek();
            }
            else
            {
                if(dot == 0)
                {
                    result = 10 * result + op - '0';
                    op = cin.peek();
                }
                else
                {
                    result += pow(10, dot) * (op - '0');
                    dot --;
                    op = cin.peek();
                }
            }
        }
    }
    return result;
}

猜你喜欢

转载自blog.csdn.net/qq_41480330/article/details/82468177
今日推荐