• 締切済み

逆ポーランド記法

電卓もどきのアルゴリズムを教えて下さい 指定された数式を解読して、演算結果を求める処理を作成したいのですが・・・・ 今考えている手順は (1) 数式を解析して 逆ポーランド記法の中間言語にして於いておく (2) 逆ポーランド記法の中間言語を演算して答えを求める と考えているのですが・・・ << 例 >>  演算式 1+2×3=    答え 7  演算式 (1+2)×3=  答え 9 大昔の知識ですのでもっとシンプルな方法が有りましたらアドバイス頂けませんでしょうか?

みんなの回答

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

お手軽に作りたいなら #1 の再帰下降解析がお勧め. 「入力された式をすぐに計算してそれでおしまい」のときには関数から return するときに「自分が担当した部分式の結果」を返せばいいし, 「入力した式を一度記憶して, あとで計算する」という形であっても入力された式を簡単に「構文木」に変換できます. いずれにしても, 「基本パターン」はできあがっているので, パターンに従う限り間違いようがないはずです. 問題点は複雑な構文になると「再帰がとても深くなる」ことで, これがいやだと LR系 (式の解析なら演算子順位解析あたり) を使うことになります. 演算子順位解析は「スタックを使って式を RPN に変換する標準的な方法」とほぼ同じで, バックエンド (あとで計算するところ) に RPN を使うなら扱いやすいかと思います. ただし, スタックの管理を自分でやらないといけないので変なところを間違える可能性はあります. ちなみに最近のコンパイラでは RPN を使うことはほとんどないはずです. 普通は構文木を作って, その上で最適化とかかけていくんじゃないかな. 念の為指摘しておきますが「RPN」は表現方法, 「再帰下降解析」は解析方法であってこの 2つは相反するものではありません>#1. 普通はしないけど「再帰下降解析で解析して RPN で記憶する」ことも可能です... ま, しないけど.

hide3_papa
質問者

お礼

色々とアドバイスありがとうございます。 やはり「逆ポーランド記法」なんて時代遅れのようですね。 日進月歩のこの分野で30年以上も前の手法をいつまでも使ってる分けないですね・・・・・ 昔人間なので「演算子順位解析」、「構文木」、「再帰下降解析」等よく判っていません、若い人にもう少し調べてから最適な方法を検討してみます。 アドバイス有りがとうございました。

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.1

★再帰下降構文解析 ・逆ポーランド記法以外にも『再帰下降構文解析』という方法もあります。  これは再帰関数を使って数式を計算します。  例えば  (1)Factor()…数値、変数、括弧  (2)MulDiv()…乗算、除算、剰余  (3)AddSub()…加算、減算  (4)Compare()…比較  (5)Express()…数式評価  このような関数を用意して  Express()→Compare()→AddSub()→MulDiv()→Factor()→Express()  と再帰呼び出しを行うだけで加減算よりも乗除算を優先して計算してくれます。  下に参考になりそうなリンクを貼って置きます。

参考URL:
http://ruffnex.oc.to/kenji/src/dentaku2.c

関連するQ&A

  • 逆ポーランド記法

    C言語で逆ポーランド記法への変換をしようとしています. 演算子の優先順位の付け方がわかりません. 構造体の配列に数式を入れて,それぞれに優先度をつけてみたりしたのですが,いい方法でないように思います. 適切な方法を知っている方よろしくお願いします.

  • ポーランド記法、逆ポーランド記法のプログラム

    ポーランド記法、逆ポーランド記法のプログラムがわかる方、是非教えてくださいm(__)m 言語は何でもいいのでお願いします~

  • ポーランド記法(前置記法)のアルゴリズム

    ポーランド記法を使用した計算のアルゴリズムについて教えてください。 逆ポーランド記法についてはたくさんの資料が存在しますが、ポーランド記法については資料がないのでどのように考えたらよいのかわかりません。 スタック又は木構造を用いて計算するアルゴリズムをお願い致します。

  • 逆ポーランド記法における単項演算子などの処理

    開いていただきありがとうございます。 質問内容は題名の通りなのですが、 中置記法の式を逆ポーランド記法に変換して計算を行う際に単項演算子をどのように扱うかで悩んでいます。+-などのように文脈に応じて意味合いが変化するものもあり、もうひとつスマートに処理することができません。 また前置・後置インクリメントなどに対応するとしたらなおざりに処理するわけにもいきませんし、三項演算子に至ってはどのように処理すればいいのかさっぱりです。 電卓に留まらず、簡単な処理系に組み込むという前提で、これらをどのように使えばよいかご教示いただければと存じます。

  • 電卓ソフトを作るには逆ポーランド法で良いのですか?

     プログラミングの勉強をしながら式入力型の電卓を作りたいと思い調べたところ「逆ポーランド法」を知りました。  まず四則演算出来るものを作り最終的には関数電卓を目指そうと思っているのですが、この「逆ポーランド法」を取り入れた計算プログラムを学べば良いのでしょうか?もっと適している他の手法はありますか? 公開されている式入力型の電卓ソフトはどのような手法でプログラムされているのでしょうか?(なかなか式入力型のサンプルが見つからなくて…。)  言語はActiveBasicを使用していますが、情報が少ない為VisualBasicのサイトで勉強しています。 宜しくお願いいたします。

  • BNF記法について

    最近質問させていただいたものですが、また分からな いことがあり、質問させてください。 ある、アルゴリズムの問題集をやっていて、BNF記法に 従った数式を解析して計算するというものでした。 BNFの定義として、 式=項 | 式 加法演算子 項 項=因子| 項 乗法演算子 因子 因子=数 加法演算子='+'|'-' 乗法演算子='*'|'/' となっています。 そのテキストで、例として、 項=3*4/5 というのがありました。これは理解できました。しかし、 式=1+2+3*4/5-6 というのが理解できません。 式=式 加法演算子 項 と、項=項 乗法演算子  因子 というのを再帰的に当てはめていくのだと思うのです が、式として成立させるのは定義からして無理だと 思うのですが。1+2+3*4/5-6を式として解釈するには どのようにしたらよいかお教えください。よろしく お願いいたします。 ちなみに、1+2+3*4/5-6は、問題集に載っているアルゴリズムで問題なく解けました。  

  • 逆ポーランド記法への変換方法を教えてください。

    Visual Studio C++ 6.0で逆ポーランド電卓のプログラムを作っていますが、式の変換方法がわからないので教えていただければ助かります。 たとえば (8 + 9 * -8) * 10 だと 8 9 -8 * + 10 * に変換できますが、  -(8 + 9 * -8) * 10 だとどう変換すればよいのかがわかりません。

  • 逆ポーランド記法の変換法

    以前逆ポーランド記法の優先順位について質問したのですが、いまいち変換法が分かりません。 例1 A+B*(C+D)+E →ABCD+*+E+ ABとCDがなぜ一緒になるのか。 例2 (A+B)*(C-D)→AB+CD-* なぜ例1のABとCDは、ABCDになって、こっちはAB+CDなのか。なぜ*が一番後ろなのか。参考書は2冊ありますが、見ても?です。手順を詳しく説明して頂ける方、よろしくお願いします。

  • C言語で逆ポーランド演算式をスタックを用いて表現するには

    C言語でスタックを使って逆ポーランド表記の演算を行うプログラムを作っています。 正の整数の場合はできたのですが、小数や負の数にも対応できるように変えるにはどうしたらよいのでしょうか? 例えば、スペースで区切られた 1.2 4.2 -3.2 + * と言う様な値を入力してちゃんと計算できるようにしたいのですが・・・。

  • プログラミングについて

    次の問題と似た問題が試験で出るのですがまず例となる問題の答えにどうしてもたどりつけませんどなたか教えてくださいお願いします。 逆ポーランド記法による完全な整数電卓を作成すること仕様は以下の通り INで逆ポーランド記法入力をする OUTで結果を入力する 数値は複数桁対応(3桁まででよい) 数値と数値の間は1つ以上のスペースで区切られる 乗算は、シフト命令をうまくかうこと 除算は、商だけでよい スタック、サブルーチンをうまく活用すること たとえば、文字列を数値に変換する部分や、各演算部分をサブルーチン化するシュミレータによる動作確認をすること

専門家に質問してみよう