【OJ】表达式求值(加减乘除和括号)简化版

编写目的

刷OJ题的总结,也作为《数据结构》重新学习的笔记,用到了C++的标准库,因此可以简化一些操作。

题目描述

对简单的算术表达式求值。运算符包括+,-,*,/,(,),#。参加运算的数均为整数。

特别说明:

1)实验课请按照数据结构(C语言版)p53页算法3.4直接进行改编。

2)要实现算法3.4,还需要编写的函数如下:初始化栈函数--InitStack()函数,入栈函数--Push()函数,取栈顶元素函数--GetTop()函数,运算符判断函数--In()函数,运算符优先级判断函数--Precede()函数,出栈函数--Pop()函数,运算操作函数--Operate()函数。

输入

每行输入一个简单的算术表达式,如输入表达式:3*(7-2)

输出

与输入相对应,逐行输出表达式对应的运算结果。如上面输入表达式的运算结果为:15

样例输入

3*(7-2)
4+2*3-10/5

样例输出

15
8

解题代码

思路介绍:
每次读str[i]字符的时候,分为两类:运算符和数据符。如果是运算符则存储到栈中(如果满足优先级条件,则进行运算,把结果存入栈中);如果是数据符暂时存在一个字符串中,等待多个连续数字读完了,再合并成一个整数写入栈中。

简化说明:
完全参考《数据结构C语言版》(严蔚敏 李冬梅 吴伟民编著 人民邮电出版社)
使用C++标准库中的stack,从而省略了自己编写Stack。
这些代码是实际OJ题,提交到OJ网已经通过的代码。

#include 
#include 
#include 
using namespace std;


/**
 *  判断优先级
 */
char Precede(char ch1, char ch2)
{
    if(ch1 == '#')
    {
        if(ch2 == '#')      return '=';
        return '<';
    }
    if(ch1 == ')')          return '>';
    if(ch1 == '(')
    {
        if(ch2 == ')')      return '=';
        else                return '<';
    }

    if(ch2 == '(')          return '<';
    if(ch2 == ')')          return '>';

    if(ch1 == '+' || ch1 == '-')
    {
        if(ch2 == '*' || ch2 == '/') return '<';
    }

    return '>';
}

/**
 * 进行简单二元运算
 */
double Calc(double num1, double num2, char calc)
{
    double result=0.0;
    switch(calc)
    {
    case '+':
        result = num1+num2;
        break;
    case '-':
        result = num1-num2;
        break;
    case '*':
        result = num1*num2;
        break;
    case '/':
        result = num1 / num2;
        break;
    default:
        break;
    }
    return result;
}

// written by Smileyan
int main()
{
    // 分别用来存储运算符和数据
    stack<char> optr;
    stack<double> opnd;
    char str[180];
    int i;

    while(cin>>str)
    {
        i=0;
        // 把最后的字符替换成#
        while(str[i] != '\0')   {   i++;   }
        str[i] = '#';
        str[i+1] = '\0';

        // 栈底写入#作为结束符
        optr.push('#');
        i=0;

        // 用来存储数字
        string data;

        while(str[i] != '#' || optr.top() != '#')
        {
            // 如果是数字,则暂时写入data中,等待合并成一个整数
            if(str[i]>='0' && str[i]<='9')
            {
                char strTemp[5];
                strTemp[0] = str[i];
                strTemp[1] = '\0';
                data.append(strTemp);
                i++;
                continue;
            }

            // 当当前字符不是数字的时候,则需要把之前的数字进行合成
            int num = atoi(data.c_str());

            // num==0表示data为空
            if(num!=0)      opnd.push(num);

            // 清空data
            data.clear();

            // 判断优先级,进行入栈出栈操作
            switch(Precede(optr.top(), str[i]))
            {
            case '<':
                optr.push(str[i]);
                i++;
                break;
            case '=':
                optr.pop();
                i++;
                break;
            case '>':
                double num1 = opnd.top();
                opnd.pop();
                char ch = optr.top();
                optr.pop();
                double num2 = opnd.top();
                opnd.pop();
                double result = Calc(num2,num1,ch);
                opnd.push(result);
                break;
            }
        }
        cout<<opnd.top()<<endl;
    }

    return 0;
}

总结

因为自己基础不扎实,学习这个花了不少时间。继续刷题吧。

Smileyan
2019年9月17日

你可能感兴趣的:(C/C++,我刷OJ题)