コンソール型計算プログラムをつくりたいんだけど part01

はじめに

件の地震の影響で多少暇ができたので、1年後に控えた就活のために、Webテストで出てくるような分数を含んだ数式をすぐソルヴできるコンソール型の計算機が欲しいなぁと思いまして。まぁRubyIRBとかRでもいいんですけど、分数があると括弧を補充する必要があるじゃないですか、つまり何が言いたいかと言うと:
\frac{7}{13} \div \frac{21}{5}
っていう数式は、1行で書こうとすると
(7/13)/(21/5)
って書かなきゃですよね?*1でもこれを時間がない中、数式の頭から入力していくと
7/13
まで入力したところでこの分数を括弧で括る必要があることがわかり、カーソルを頭に戻して始め括弧を加えることになります。これが
\frac{7}{13} + \frac{21}{5}
なんて数式だったら、これは
7/13+21/5
って書けばいいですよね。これは計算規則で「乗除の計算は加減の計算より先にやらなくてはいけない」という決まりがありますから。と言うわけで、俺が今回つくりたいコンソール型計算プログラムは、

  • 四則計算の記号として「÷」と「/(分数)」の2つを別々に用意する。

そして余力があれば

  • 多項式も方程式も解けるようにする

っていうのもあればいいなと思っています。だってWebテスト、方程式を解けっていうのもありますよね、その両方に対応出来れば尚によろしいので。

数式の分析

で、早速C++で開発を始めたわけです(環境はVC++2008 Express Editionです)が、最初の難関にぶち当たりました。それは数式の分析です。構造言語学みたいなところですね。これって大学の授業でやったようなやってないようななんですよ。なのでひとまずは初心者の素人考えでアプローチしていきます、そのうち本を読みだすかもしれませんし、読まないかもしれません。
数式はオペレータとオペランドの2つから成り立っています。オペレータは演算子と言ったりもしますが、数式では「+」とか「−」とか「×」とか「÷」とか、そう言うのがオペレータです。オペランドはひとまずここではオペレータ以外のもの、ここで扱いたい数式では特に数字だと思ってくれて差し支えないと思います。例えば、
1+2
とあったら、「+」がオペレータで、その両脇にある「1」と「2」がオペランドです。
今自分の中で顕在化している問題は2つありまして、まぁこの2つは結局1つのソリューションで解決できると思うのですが、1つは計算順序の問題、もう一つは括弧の問題です。
プログラムは入力された数式を数式の左から順に分析をかけて行くアルゴリズムで行こうと思っています。なので例えば
1+2*3-4
って数式は、頭から順番に読んでいくのですね。ここで、
1+2*3
まで読んだ段階で、プログラムには「先に2*3を計算して、その計算結果と1を足さなければ」と判断しなければいけないわけです。この判断をどのようにさせるかというのが前者の問題。
後者は、
(1+2)*(3-4)
みたいな数式はどうするかです。まぁこの場合は、数式の()内を内側から拾って行って順番に計算させて戻す、つまり
(1+2)*(3-4)―[1+2=3,3-4=-1]→3*(-1)→-3
という流れかなぁと思っています。この考え方を前者の問題にも応用して、数式の優先オペレータから順に拾っていって計算して戻す、という流れがいいのではないかと思っています。そうするとこれは再起関数を使うことになるでしょうね。

とりあえず今回は以上です。

p.s.:多分IRBにオペレータのオーバーロード機能があると思うから、それで頑張れば今回やりたいことって出来るんだと思うんですけど、まぁこれもC++の手習いなので。前もどっかで書きましたが、Cでやりたいことを書いていって、必要に応じてC++の知識を足していったので、coutとかcinとかまともに使えないんですよ私。なのでC++を一からやり直すつもりでこのプロジェクトをやっていくつもりです。

*1:「(7/13)/(21/5)」と「7/13/21/5」の計算結果が違うというのは、大丈夫ですよね?わからない人はエクセルにでも計算させてみてください。