【OJ】式評価(加減乗除と括弧)簡略版


作成の目的
OJ問題のまとめも、『データ構造』の再学習のノートとしてC++の標準ライブラリを使用しているので、いくつかの操作を簡略化することができます.
タイトルの説明
単純な算術式を評価します.演算子には、+,-,*,/,(,),#が含まれます.演算に参加する数はすべて整数です.
詳細:
1)実験課はデータ構造(C言語版)p 53ページアルゴリズム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]文字を読むたびに、演算子とデータ記号の2種類に分けられます.演算子であればスタックに格納する(優先度条件を満たす場合は演算を行い、結果をスタックに格納する).データ文字が一時的に1つの文字列に存在する場合は、複数の連続数が読み終わるのを待って、整数書き込みスタックにマージします.は「データ構造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日