【Java】eval()を自作してみた

f:id:hira98:20190602005447p:plain

【結論】

  • JavaScripteval()に相当する処理を自作してみた。

  • ただし、逆ポーランド記法では解いていない。

  • 自力で計算する際のやり方を素直にコード化した。

  • 実装できたけど「()」や「べき乗」には対応していない。

【目次】

はじめに

前回、Java学習の一環として小町算を解きました。

hira98.hatenablog.com

しかし、´不覚にもJavaScriptの助けを借りてしまいました。

よって、今回はJavaScriptに頼らざる得なかったeval()を自作してみました。

eval()とは?

下図(JavaScriptの実行結果)のように、計算式の文字列を引数として渡すと計算結果を返してくれるメソッドです。

f:id:hira98:20190602005503p:plain

JavaScript以外にもPythonRubyにも実装されているのに、Javaで見つけることができませんでした。

実装方法の検討

eval()を実装するなら、逆ポーランド記法で実装するのが一般的です。

しかし、今回はJavaの勉強も兼ねて、あえて別の方法を取ろうと思います。

と言っても大した方法ではなく、手動で計算する時の手順をコンピュータに教えてあげるだけです。

オレオレアルゴリズムの作り方

他の人がどうやっているかは知らないですが、私がアルゴリズムを考えるときは、入力に対する出力のパターンをいくつか手計算で求めて、そこから規則を導き出して、それをコード化していきます。

落書きして手順書を作成する

複数の演算子がまとまった式を計算するときは、演算子が1つの式に置き換えて地道に計算していくしかないです。

f:id:hira98:20190603204856p:plain

「上記3つの例に従って解けばいいから!基本的には左から右に順に計算していけばいいけど、例3)みたいに掛け算と割り算は足し算と引き算より優先度高いから先に計算してね。じゃぁ、コンピュータ君、後はよろしく!!」

…的なノリでコンピュータが処理してくれれば楽でしょうが、プログラミングはそうはいきません。

人間の思考をもっと詳しく教えてあげる必要があります。

コンピュータへの教え方

私が1+2-3+5を記号の羅列でなく計算式として認識できるのは、記号を数値と演算子に判別できるからです。

まずは、判別方法をコンピューターに教えてあげる必要があります。

f:id:hira98:20190602005608p:plain

判別した後は、数値をnum配列、演算子をope配列に格納します(下図①)

次にnum配列とope配列で計算式を表してみます(下図②)

すると、ope[N]の計算に使用するnumはNとN+1で表せることがわかります((下図③)

f:id:hira98:20190602005621p:plain

ルールが見つかったので、num配列とope配列を用いて実際に計算してみます。

f:id:hira98:20190602005634p:plain

上図より、足し算と引き算は規則に従って計算できることがわかりました。

念の為、掛け算を含むケースも手計算してみます。

f:id:hira98:20190602005649p:plain

以上でコンピューターに教えるための準備は整いました。

後は手順をJava言語でまとめてあげるだけです。

手順書をJava言語に翻訳する

MyEvalクラスのeval()メソッドを呼べば使えます。

さいごに

アルゴリズムを伝えるのに文章だけだと絶対に伝えきれない自信があったので、手書きの図を載せました。

字が汚いのは勘弁して下さい💦清書する気力までは起きませんでした。