オリアプ#4

今回も四則演算機能について考えていきます。

計算アプリについて一通り調べました。しかし、もともと式を準備しておいて、その中に引数として私て計算することが多かったです;;

例えば、num1 *  num2 のようにすることで、num1の中身の数字と、num2の中身の数字を掛け算して出力する的な公式を元々記述して、そこに当てはめる形が多かったです。

となると、条件式で+の場合は
if memo.include?(+)
if else memo.include?(-)
if else memo.include?(/)
if else memo.include?(*)
else
end

と全ての記号の時それぞれで処理を準備してあげることで、計算する型はでき上がります。そこでメモ情報をうまく取り出す方法があれば、当てはめることができます。

もしくは、正規表現にて数字と+ , - , * , / を含むメモにマッチするようにすることもできます。\d もしくは 0-9 で数字にマッチします。

.match(/\A\d{3}[-]\d{4}\z/)

上記の記述にて郵便番号にマッチすることができるのですが、{3}が3つの連続する数値という意味だったので、0~9のに変えてみましたが、マッチしませんでした。なんかしら方法があるんでしょうが、精度を上げる時に利用するだけで、現状では無駄な知識になりそうなので、とりあえず、放置しておきます。

if @scanner.scan(/\d+|[\+\-\*\/()]/) 

とあるサイトで発見しました。@scannerのところにメモを代入すれば、使えそうです。

 

次にメモの中から数値を取り出す方法について考えます。

えー、思いつきません。ということで、当初想定していたことはどんなことだったの
か、を言語化してみることにします。

def ~ end でメソッドを定義して、実行することで、処理ができるなら、それをアプリの時に実際に利用してみようと考えた。
そのため、gets.to_iで数字だけを入力させれば達成できる。そんな記述しかしてきていません。

今回実装したいのは、文字列から、数値を取り出し、計算する。そのため、完全に新しい考え方が必要になります。最悪、画面右側に計算欄を作って無理やり達成するしか...w

 

StringScannerなるものを見つけました。簡単に学んだことを実践したので、まとめてみます。これを使えば、なんとかなりそうです。

配列.scan(正規表現?)の形でscanすることができます。深くまで理解できてませんが、動きが理解できたので、ターミナルの実行を元にまとめます。

[1] pry(main)> s = StringScanner.new('1444+300')
=> #<StringScanner 0/8 @ "1444+...">
[2] pry(main)> s.scan(/\d+/)
=> "1444"
[3] pry(main)> s.scan(/\++/)
=> "+"
[4] pry(main)> s.scan(/\d+/)
=> "300"

 

[ 1 ]での記述をまとめます。 s という配列に newで生成された情報('1444+300') を入れています。出力されている#<StringScanner 0/8 @ "1444+...">の@はスキャン位置になります。0/8は8このうち、スキャンした数は0という意味っぽいです。

[ 2 ]では、スキャンを開始しています。正規表現は\dで数字とマッチした時に出力されます。この時、スキャンの情報が変わるので、
#<StringScanner 4/8 "1444" @ "+300">
となります。既に8個のうち4つはスキャン済みです。スキャンの位置は+の前になります。

[ 3 ]では、正規表現で\+にマッチするようにしています。ここは条件分岐を使って、四則演算に対応させればなんとかなりそうです。
#<StringScanner 5/8 "1444+" @ "300">
となり、既に8個のうち5つはスキャン済みです。スキャンの位置は300の前になります。

[ 4 ]では、[2]と同じように数字にマッチするようにしています。
#<StringScanner fin>
となり、スキャンは終了します。

実際にどこがスキャンされているのか確認したい場合は、配列だけで出力すれば確認することができます。今回であれば、配列sをスキャンしているので、s だけで実行します。

 

それでは、早速実践してきます!!
はい、文法エラーが発生しました。

文字数が多くなってきたので、今回はここまで!