PTA7-4サフィックス評価(25ポイント)(質問+コード+詳細コメント+ピット分析)

私たち人間は、たとえば3 + 5 * 2 その値など「中置」を書くことに慣れてい  ます13(ps人間が中置スタイルに慣れているのはなぜですか?それは、中置スタイルが接尾スタイルよりも
使いやすいからですか?)また、コンピュータは「接尾スタイル」(「逆ポーランド記法」とも呼ばれます)に慣れています。上記のインフィックス式に対応するサフィックス式は次のとおりです。  3 5 2 * +
次に、入力したサフィックス式を評価してください。

入力フォーマット:

単一の行に接尾辞、运算数および运算符スペースで区切られ、オペランドの長さを超えない6ビットのみオペレータ+ - * / 4本を。

出力フォーマット:

サフィックス値を小数点以下1桁で1行に出力します。

入力サンプル:

3 5.4 2.2 * +

出力例:

14.9

 

質問:文字列を指定して、そのサフィックス式の結果を計算します

方法:典型的なスタック操作。数値が読み取られると、スタックにプッシュされます。演算子が読み取られると、スタックの上部にある2つの数値がポップされて操作が実行され、結果がスタックに追加されます(STL文字列とスタックを使用して簡単に実現できます) )

ノート分析:

  • 負の数と小数を判断する
  • 減算および除算演算を実行する場合、2番目のポップアップ番号は減算または被除数です
  • 質問によると、計算が間違っているため、除数は0にはならず、質問はエラープロンプトを表示しません

ACコードは次のとおりです。

#include<bits/stdc++.h> 
using namespace std;

stack<double>num;                 //声明一个栈,储存操作数

double cal(double x1, double x2, char c){          //给定两个数(x1先弹出)和操作符,得到计算结果
    if (c == '+')  return x1 + x2;
    if (c == '-')  return x2 - x1;               //注意是x2 - x1和 x2 / x1
    if (c == '*')  return x1 * x2;
    if (c == '/')  return x2 / x1;           
}

double change(string s) {                     //把字符串转成相应的数值
    double ans = 0, sign = 1;                //sign为符号,初始为1
    if (s[0] == '-') {                       //先判断负数
        sign = -1;                           //标记符号为负
        s.erase(s.begin());                 //把首位的负号抹去
    }
    int cnt = 0, flag = 0;                   //cnt是小数位的位数(即最后小数点要往左移多少位),flag表示是否发现了小数点,二者初始都是0
    for (int i = 0; s[i]; i++) {             //遍历字符串
        char c = s[i];                              
        if (c != '.') ans = ans * 10 + c - '0';          //如果是数字,则转换成对应的值(高位乘10加本位)
        else  flag = 1;                //发现了小数点,flag改为1
        if(c != '.') cnt += flag;      //小技巧:当发现了小数点之后,cnt每次都要+1,在此之前不变,即加0;而刚好和flag同步了,则可以直接加flag;这里的判断是因为,刚发现小数点时,cnt不加
    }
    if(cnt)  ans /= pow(10, cnt);                 //小数点移位操作,即除以10^cnt
    return sign * ans;                       //最后连带符号返回字符串对应的数值
}

int main() {
    string s;
    double ans;
    getline(cin, s);                     //对于中间有空格的字符串,要用getline
    for (int i = 0; s[i];) {             //遍历字符串
        string temp = "";                
        while (s[i] != ' ' && s[i])       //得到每两个空格之间的部分
            temp += s[i++];                  //string类可以把字符直接加到末尾
        if (s[i] == ' ')                  //跳过空格
            i++;
        if (temp == "+" || temp == "-" || temp == "*" || temp == "/") {       //如果是操作符
            double x1 = num.top();             //弹出两个数
            num.pop();
            double x2 = num.top();
            num.pop();
            ans = cal(x1, x2, temp[0]);         //进行运算
            num.push(ans);              //再把结果压入栈中
        }
        else                           //是操作数,就把string转换成double,并入栈
            num.push(change(temp));

    }

    printf("%.1f\n", ans);                          //输出最终结果
    return 0;
}

//ブログをよく読んでいて、ブログがenoki mushroomと同じくらい詳細で、コメントが非常に詳細であることを知っています。スプレーしないでください!

//見た後、これ等がある良い習慣ああ〜

おすすめ

転載: blog.csdn.net/qq_45472866/article/details/106697758