2017-07-13 3 views
-1

を取得し、私はFlexでシンプルな1個のファイル言語に取り組んでいたと私は問題に出くわしたに等しい異なります。スタック後置記法の評価は中置Calcが

中置計算式は、1 + 2 * 5 -32です。電卓では、-21になります。

私のpostfixの計算式は次のとおりです。1 2 5 32 - * +、私の電卓で55に等しいです。ここで

は私のFlexコードです:

%{ 
#include <cstdio> 
#include <cstdlib> 
#include <string> 
#include <iostream> 
#include <stack> 

using namespace std; 

stack<int> numberStack; 
int a; 
int b; 

extern "C" int yywrap() { } 
%} 

%% 

[ \t\n] ; 
[0-9]+ numberStack.push(atoi(yytext)); 
"+" a = numberStack.top(); numberStack.pop(); b = numberStack.top(); numberStack.pop(); numberStack.push(a+b); 
"-" a = numberStack.top(); numberStack.pop(); b = numberStack.top(); numberStack.pop(); numberStack.push(a-b); 
"*" a = numberStack.top(); numberStack.pop(); b = numberStack.top(); numberStack.pop(); numberStack.push(a*b); 
"/" a = numberStack.top(); numberStack.pop(); b = numberStack.top(); numberStack.pop(); numberStack.push(a/b); 

%% 

int main(int argc, char *argv[]) 
{ 
    yyin = fopen(argv[1], "r"); 
    yylex(); 
    fclose(yyin); 
    cout << numberStack.top() << endl; 
    numberStack.pop(); 
    return 0; 
} 

(私はFlexで少しさびていて、特にコピー貼り付けたCコード)物事の私の方法を言い訳してください、私はポーランドのリバース表記上のビデオを見ましたそれを使用するスクリプト言語を作りたいと思っています。作成には約5分かかりました。

スタックのタイプがintであるため、浮動小数点数が0と表示される可能性が最も高いので、除算はできません(しかし、残しました)。

私のポーランドの逆記法電卓スクリプトでは、1 2 5 32 - * +55に変換する理由を説明できますが、正解は-21ではありませんか?

+1

デバッガを使用してコードをステップ実行する必要があります。変数の値を調べ、必要な結果とどのように異なるかを確認します。 – Ron

+0

あなたはRPNがなぜ存在するのかを知りました。演算子のバインドと順序については明示的ですが、電卓は「正しいことを」実行する必要があります。計算機で1 + 2 *(32-5)を実行すると、それに同意します – pm100

+0

Cでは、2つの 'int'sを分割すると' int'が返されます。浮動小数点数を使って作業したい場合は、 'double'のスタックを使います(そして、小数点を持つ数字を認識するために数値パターンを修正してください)。 – rici

答えて

1

あなたのコードの結果が間違って(ほとんど)何もありません。

RPNへの1 + 2 * 5 - 32(通常の演算子優先順位に従って)の正しい変換は、1 2 5 * + 32 -です。 RPN 1 2 5 32 - * +1 + 2 * (5 - 32)

の翻訳です。あなたのコードには、正しい機能の逆を計算しているという問題があります。つまり、5 32 -は-27ではなく27を返します(そして32 5 -は27ではなく-27を計算しています)。同様の問題は/と表示されます。 (+*は可換であるため、問題は気付かれません)。

だから、すべてのアクションで

abが逆転しなければなりません。

グローバル変数ab使用する必要もありません:明らか

"-" { int right = numberStack.top(); 
     numberStack.pop(); 
     int left = numberStack.top(); 
     numberStack.pop(); 
     numberStack.push(left - right); 
     } 

が、スタックが.top()を呼び出す前に空でないことを確認した方が良いでしょう。

関連する問題