接尾辞/中置/プレフィックス表現についての概要

今何が起こっているのか考えてみては数9.23

私は最近、失ってしまったのはなぜ少し良いものは、神々が妖精の事の今年の数十の前にとても良いレース性能をシミュレートすることができます持っています

私はむしろクラス疲れに戻ってこない、直接バックエンジンルーム内のクラスに私に言った私の物理の先生にとても感謝しています、彼は非常に啓発された非常に感謝し、最悪の先生があなたに言ったとき、まあ文化の研究に従事して戻ってくるそして、良い仕事をしていなかったという人種はないことを私に言いました私がしようとしますqwq私はスラグの物理学に焦点を当てたが移動された話をしましょう

さて、上記のはナンセンスです。

この表現は、それをコードに見えたと思うために下に書かれたほど良くない学校の前に私の良い朝ですが、私はこの瞬間を聞いていた昨日は物事の書き方を忘れて評価され、

実際には、ツリー内のシーケンスの順序が木である後トラバーサルシーケンスへのプレリュードとして見られ、その後、対応を挿入することができたときに、我々は式を評価するのでプレフィックスとサフィックス中置形になりますなぜ 

だから、別のトラバーサルのシーケンス式は、我々は接頭辞と接尾辞の計算式について話をここになります方法とどのようにPostfixに中置を変換する計算に異なるを評価し、これは一般的です

すべての式は、私はあなたが知っていないとは考えていない言及するスタックに従事するように評価します知っている必要があります。 

これは、インフィックス式は算術または論理式の一般的な表現、中置形の中間オペランドの演算子であり、我々が最も頻繁に書き込まれた概念中置式(中置表記)を導入します。

人間の脳は、中置式を理解し、分析するのは簡単ですが、コンピュータが、それは非常に複雑である中置式であり、式のため、計算値、通常は接頭辞や接尾最初の中置式に変換する必要がありますが表現、

次に、評価値。表現の接頭辞または接尾辞値を計算するコンピュータは、非常に簡単です。

接頭式(接頭表記、ポーランド)オペレータプレフィックス式オペランドに先行します。

コンピュータ評価のプレフィックス表現:

右から左への走査からの発現、数字ながら、演算子を使用してスタックに数、オペレータの顔、2つの数のポップアップスタックは、それに応じて計算され(そのOPトップ素子の上部要素)、その結果スタック。

直接プロセスを繰り返し左端式に、式の最後の演算結果により得られた値です。

例えば接頭語表現 " - ×+ 3 4 5 6":

(1)左右のスキャンに、スタックに6543と、

(2)+演算子を満たし、SO 3及び4(ノートスタック34が、この時スタックに適用される)ポップ、算出4 + 3の値は、7すぎると、スタック7。

(3)次に×演算子であり、従って、ポップアップ7 5、7×5 = 35、スタック35を算出しました。

(4)最後に - 演算子、35-6の計算値、すなわち29には、最終的な結果ということになります。

その後、我々は、計算後置式を考えます

私たちの上に左から右にわずかに異なるため、この表現に遭遇すると、デジタル符号が遭遇されるプッシュすることが便利である結果を得るために最後の一押しになるまで行われた操作のスタック演算結果から上位二つの数字であります

後置表現はまた、我々は、直接アナログとすることができるので、この式は、括弧が存在しないことを特徴とする逆ポーランド記法と呼ばれているが、我々は、計算中置式を議論するためにここにあります

つまり、我々は方程式を書くが、最も計算我々は表現に変換表現の接頭辞または接尾辞に変換するための2つのメソッドを持っているサフィックスに上記の式に従った方法については、ここで言って評価

私たちはそのほんの括弧整数のみ入力正当な例を想定してどのように変換、ここでの話をしてみましょう:

中置式である:1 +(2-3)×4 + 4/2

後置式に対応する次のとおりです。123--4 42 * + / +

どのようにして後置記法に式を中置でしょうか?私たちは、店のオペレータにそれを使用し、スタックの助けを必要としています。

(ブラケットを含む)まず、各種の演算子優先順位(より多く、より高い優先度)を次のように

1:(括弧は最低優先qwqであることに注意してください

2:+ -

3:* /

4:^

5 :)

ここだけのアカウントにフォームの電源を取ります 

左から右に中置するための式はトラバース入力されました:

あなたはデジタル持っている場合は1)、後置式の終わりに直接;

2)あなたは、オペレータが発生した場合は+、 - 、*、/:

まず、スタックが空であるかどうかを判断します。もしそうなら、このオペレータは、直接スタックに。ない場合は、スタックの現在のトップを確認してください。上部要素の優先度があれば以上で、このオペレータレベル、トップ要素が後置表現に追加された頂部要素をポップし、決意を続けます。決意が満たされていない、またはスタックが空である場合、オペレータは、押します。上記の手順の後、ことが注目され、オペレータが最終的にスタックします

3)如果遇到括号:如果是左括号直接入栈。如果是右括号弹出栈中第一个左括号前所有的操作符,并将左括号弹出

4)字符串遍历结束后,如果栈不为空,则弹出栈中所有元素,将它们添加到后缀表达式的末尾,直到栈为空。

通过上述过程 我们就得到了 这个中缀表达式 对应的后缀表达式 那么 我们怎么计算后缀表达式也清楚了 但是这种发现有点 麻烦 我们还要记录这个后缀表达式是什么 

对于一些题目 不需要你输出 后缀表达式 那我们考虑直接计算 不记录这个后缀表达式 直接将两步结合起来;

我们考虑开两个栈 一个数字栈 一个符号栈 我们读入当前的中缀表达式 遇到数字 我们将其压入数字栈 遇到符号 按照刚才的方式处理

对符号栈进行处理 对应优先级的顺序 也就是说 对于一个操作符  我们将优先级大于等于当前符号的 都计算出来 方法类似于后缀表达式 一个符号 两个数字 计算结果压入栈中;

所以我们无需计算出具体的后缀表达式 直接计算即可;

鉴于写文章的作者比较懒 所以以上都没有代码 不过luogu上倒是有后缀表达式 以及简单的中缀表达式计算的例题 如1449 但为啥都是普及-啊

所以 只有计算中缀的一个题目 涉及 负数 多位数字的处理 以及加 减 乘 整除 乘方 括号 多种运算

给出一个表达式,其中运算符仅包含+,-,*,/,^(加 减 乘 整除 乘方)要求求出表达式的最终值。

数据可能会出现括号情况,还有可能出现多余括号情况。

数据保证不会出现大于或等于231的答案。

数据可能会出现负数情况。

输入格式

输入仅一行,即为表达式。

输出格式

输出仅一行,既为表达式算出的结果。

输入样例:

(2+2)^(1+1)

输出样例:

16

我们按照上面的思路来一遍就好了 注意好好处理数字 

#include<bits/stdc++.h>
using namespace std;
stack<int> num;
stack<char> ops;

inline int mul(int a,int k) {//慢速幂???
    int res=1;
    while(k--) res*=a;
    return res;
}

void cal() {//计算表达式的值 按照后缀表达式的方式
    int num1,num2,num3;
    num1=num.top(); num.pop();
    num2=num.top(); num.pop();
    char op=ops.top(); ops.pop(); 
    if(op=='+') num3=num2+num1;
    else if (op=='-') num3=num2-num1;
    else if (op=='*') num3=num2*num1;
    else if (op=='/') num3=num2/num1;
    else num3=mul(num2,num1);
    num.push(num3);//计算结果压入栈中
}

int main()
{
    string str;
    cin >> str;
    string left;
    for(int i=0;i<str.size();i++) left+='(';
    str=left+str+')';//处理多余括号的情况 可以多左括号 但是多右括号就麻烦了 
    for(int i=0;i<str.size();i++) {
        if(str[i]>='0'&&str[i]<='9') {
            int j=i,t=0;
            while(str[j]>='0'&&str[j]<='9') {
                t=t*10+str[j]-'0';
                j++;
            }
            num.push(t);//处理多位数字的情况 题目并没有保证是10以内的数字
            i=j-1;
        }
        else {
            char c=str[i];
            if(c=='(') ops.push(c);//左括号 直接入栈 
            else if(c=='+'||c=='-') {
                if(c=='-'&&i&&!(str[i-1]>='0'&&str[i-1]<='9')&&str[i-1]!=')') {//处理负数的情况 将减去一个数 改成+负数 
                    int j=i+1,t=0;
                    while(str[j]>='0'&&str[j]<='9') {
                        t=t*10+str[j]-'0';
                        j++;
                    }
                    num.push(-t);
                    i=j-1;
                }
                else {
                    while(ops.top()!='(') cal();
                    ops.push(c);
                }
            }
            else if(c=='*'||c=='/') {
                while(ops.top()=='*'||ops.top()=='/'||ops.top()=='^') cal();//优先级大于等于加减的计算完
                ops.push(c);
            }
            else if(c=='^') {
                while(ops.top()=='^') cal();//乘方的优先级最高
                ops.push(c);
            }
            else if(c==')') {
                while(ops.top()!='(') cal();//遇到右括号
                ops.pop();
            }
            else 
                cout<<"sbsbsbsb"<<endl;//无解?????
        }
    }
    cout<<num.top()<<endl;
    return 0;
}

 

这啥鬼畜代码 我自己都看不懂了 中午好好想想

 

おすすめ

転載: www.cnblogs.com/Tyouchie/p/11570638.html