未経験エンジニア転職活動中にあった技術テストです。
備忘録と復習をかねて、記事にしました。
課題
ポーランド記法された数式を計算する処理を実装し、以下の数式と答えがあっているか確認する
問題1:
-
- 1 2 + 3 -5
回答1: -6
- 1 2 + 3 -5
問題2:
/ + 2 2 + 3 5
回答2: 0.5
問題3:
-
- 2 2 + 3 5
回答3: -4
- 2 2 + 3 5
問題4:
-
- 3 11 + 4 2
回答4: 8
- 3 11 + 4 2
問題5:
-
- / 15 - 7 + 1 1 3 + 2 + 1 1
回答5: 5
- / 15 - 7 + 1 1 3 + 2 + 1 1
ポーランド記法とは?
演算子の後ろに数値を2個並べて演算子とその数値2つを計算する方法
例1
通常の計算式
1 + 2
ポーランド記法
- 1 2
例2
通常の計算式
(1+5)*(2+3)
ポーランド記法
-
- 1 5 + 2 3
- 1 5を計算した後+ 2 3を計算する
- 6 5 となり、答えは30になる
この処理を実装し、与えられた数値に対して正しく答えが出るか確認をする
ポーランド記法
実装
def calc(num1, num2, ope)
i = num1.to_f
j = num2.to_f
return i + j if ope == "+"
return i - j if ope == "-"
return i * j if ope == "*"
return i / j if ope == "/"
end
def input(str)
num_box = []
str.reverse_each do |num|
if num =~ /\d/
num_box << num.to_i
else
a = num_box.pop
b = num_box.pop
num_box << calc(a, b, num)
end
end
p num_box
end
str = gets.split.map
input(str)
calcメソッド
後述するinputメソッドで入力された値を計算するためのメソッドです。
答えの中に小数点以下の値がでてくるものもあるので、to_fメソッドで小数点以下も表示できる状態で計算処理を行います。
受け取った4種の演算子に応じて、それぞれの処理を行わせるような記述になっています。
inputメソッド
入力された値は文字列として変数strで定義します。
このstrの後ろから順に操作を行います。
入力された文字列が数字の場合(正規表現を使用)num_boxに格納します
その他、つまり演算子の場合はnum_boxの右から順に値を取り出し、calcメソッドで計算してまた配列に入れます。
これを繰り返し、最終的にstr全てに対してこの処理を行った時に配列に残る値が計算結果になります。
例
-
- 1 2 + 3 -5
str = [*, + , "1", "2", +, "3", -5]
str.reverse = ["-5", "3", +, "2", "1", +, *]
num_box = ["-5", "3"]
num_box = ["-2"]
[+, "2", "1", +, ]が残ります
num_box = ["-2", "2", "1"]
num_box = ["-2", "3"]
[]が残ります
num_box = [-6]
- 1 2 + 3 -5
このような感じで演算子を見つけると、num_boxに入った新しい値から2つを使って計算し、num_boxに格納する
を繰り返すことで計算結果が得られました。
まとめ
左から順に計算していくというのが演算子が連続した場合に難しかったため、式を右から見ることで演算子を見つけたら2つの値を計算するということを繰り返し行い、式の値がなくなるまで行えば計算結果が得られるという方法で実装してみました。
実装・解釈の間違い、ご意見などありましたら是非お願いします。