プロが教える店舗&オフィスのセキュリティ対策術

Cプログラミングの関数電卓のアルゴリズムについてですが、
標準入力からの文字列式を、トークンに区切り、先頭から配列型スタックに格納して、計算を行う処理を考えていて、

a-b-cという処理のアルゴリズムに困っています。
どういった解決策があるのか教えて頂けませんか??
お願いします!!

フローチャートを書くほどの事でも無いと思うので、僕が考えていたアルゴリズムを、文で記載しますが、できれば、このアルゴリズムからどうすれば解決できるかを考えて頂けたらとても助かります!!

1.
別のスタックを用意して、元々のをstack1,コピー用をstack2とし、stack1のトップからstack2に格納。(スタックの構造は二次元文字型配列)
この場合、cからstack2に格納される。

2.
演算子を見つけると、その前後の数字をその演算子によって処理。
この場合なら、c-bという処理。

3.
計算結果を、cが格納されていた、演算子の前に格納。

4.引き続き、この操作を繰り返す。

これを考えてたんですが、実行すると、(c-b)-aという式になり、違う答えが出てしまいます。加算ならば影響はでません。
きちんと(-c-b)+a の処理をさせるにはどうしたら良いかがわからないです。

お願いします!!


※返事が多少遅れるかもしれませんが、すみません!!

A 回答 (6件)

昔ながらの書き方をするとスタックを利用すること自体は


おかしいことではないと思いますよ。
この場合、どちらかといえば「2.」がおかしいんじゃないかなと思います。

まぁ二次元配列じゃなくて一次元配列にして、
二次元の部分は再帰呼び出しを使うべきなのかなーとは考えますが~
このへんは好みなんですかね?

昔つくったやつはこんな感じだったかな。。。
1. ()を探して ()の内部で再帰呼び出し
2. 単項1 演算子1 単項2 演算子2 続き に分離
3. 単項1 と 演算子1をスタック
4. 演算子1 が */ なら 単項2と演算してスタック
5. 演算子1 が +- なら そのままスタック
6. 終端まで来たらたまっているスタックを先頭から演算
7. 答えの返却

ん~もうすこし複雑だったかも
    • good
    • 0
この回答へのお礼

ありがとうございます。
確かにこの方針は学校の授業でほのめかされたやり方なんですが、
教授陣は年配の方達なので、その影響が出てるんだと思います!!

二次元配列は単純にわかりやすさですかね。。

かなりわかりやすいです。
是非使わせてもらいます!!

お礼日時:2010/06/22 17:20

>APL とか J なら「おしりから処理する」のは合理的なんですけどねぇ



他の言語の話をここで持ち出されましてもねぇ。
プログラミング言語に関する造詣が深いらしいことだけはわかりました。

>RPN にするのはちょっと中途半端感がただようんじゃないかな. 解析しつつ計算しちゃうか, 木構造を作ってから計算するか, どっちかではないかと.

数式の木を作ってから、行きがけだか通りがけだか帰りがけだかで探索すると
RPNになるという話をどこかで聞いたことがあったようななかったような。

まあ、あれですね、元の質問者さんが目指している「関数電卓」と
「a-b-cで悩んでいる」こととの間には相当隔たりがあるように思います。
まずは、(カッコを含んだ)四則演算を正確に実行できる
「四則演算電卓」を作成して、それを改良していく、というのが
早道ではないかなとも思います。
    • good
    • 0
この回答へのお礼

ありがとうございます。
指数、括弧も含める四則演算に関してですが、すでに減算以外は完成しています。
なので、後には退けなくなってしまったのです。。

お礼日時:2010/06/22 17:26

APL とか J なら「おしりから処理する」のは合理的なんですけどねぇ>#3. それでも a-b-c = a-(b-c) だから, やっぱりおかしい.


もともと最初の「スタック」は何を意図したものなんだろう.
RPN にするのはちょっと中途半端感がただようんじゃないかな. 解析しつつ計算しちゃうか, 木構造を作ってから計算するか, どっちかではないかと.
    • good
    • 0
この回答へのお礼

スタックは解析処理のためのものです。頭から一文字ずつ解析していこうと、
そういう手法で処理するためのものです。
このアルゴリズムはとんでもない失敗みたいですね…

お礼日時:2010/06/22 17:09

どう考えても、a-b-cという式のおしりから処理しようとするのは


合理的でないと思います。

私だったら、演算子の優先順位を考慮に入れて、
中置記法(a-b-cのような、いわゆる普通の書き方)から
後置記法(逆ポーランド記法、a b - c - のような)に変換した後で
処理すると思います。
もっといい方法があるかもしれません。
    • good
    • 0
この回答へのお礼

ありがとうございます。
その方式をもっと詳しく教えて欲しいです。

お礼日時:2010/06/22 17:05

私も「考え直す」ことを強くお勧めします.


多分, このままいくと加減算だけならまだしも乗除算が入ったりするとごっちゃごちゃになるでしょう. 「数式の処理」というのはコンパイラやインタプリタでは基本的なものですから, そっちの方で調べてみる方がいいと思います.
    • good
    • 0
この回答へのお礼

ありがとうございます。
でもすでに、加算、乗算、除算、指数演算、括弧内の項の演算のプログラムは
このアルゴリズムで完成させてしまっているので、後に退けない状態となっております。
確かに500行くらいの面倒なプログラムになってしまってますが。。

お礼日時:2010/06/22 17:02

>1.


>別のスタックを用意して、元々のをstack1,コピー用をstack2とし、stack1のトップから
>stack2に格納。(スタックの構造は二次元文字型配列)
>この場合、cからstack2に格納される。

このロジックは本当に必要でしょうか。
考え直した方がいいと思います。
    • good
    • 0
この回答へのお礼

ありがとうございます。
そのような回答がもらえることも予測していました。
しかし、すでに加算、乗算、除算、括弧内の項の演算、指数演算について、
このアルゴリズムで完成させたため、後に退けない状態になっております。。

お礼日時:2010/06/22 16:59

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!