前回の逆ポーランド記法プログラムの改良版
前回のプログラムの問題点
apple + lemmon
を逆ポーランド変換記法に変換しようとすると
['a', 'p', 'p', 'l', 'e', 'l', 'e', 'm', 'm', 'o', 'n', '+']
となってしまう点を何とか解決。使ったのは正規表現で、集合とは特に関係なかった。プログラムは
def reverse_polish(): LIST = list() #リスト作成 read_a_line(LIST) #一行読み込む skip_spaces(LIST) #空欄は削除する #ここから逆ポーランド変換 List1 = [] #演算数を入れるリスト&逆ポーランド記法の結果が入る List2 = ['@'] #演算子を入れるリスト import re i,n = 0,len(LIST)-1 while i <= n: if LIST[i] == "$": #$が入力されたら終了 break elif re.findall("[a-z|A-Z|0-9]+", LIST[i]): List1.append(LIST[i]) elif LIST[i] == '(': List2.append(LIST[i]) elif LIST[i] == ')': while not List2[len(List2)-1] == '(': List1.append(List2[len(List2)-1]) del(List2[len(List2)-1]) del(List2[len(List2)-1]) elif LIST[i] in ('+','-','*','/'): while less_or_equal_prec(LIST[i],List2[len(List2)-1]): List1.append(List2[len(List2)-1]) del(List2[len(List2)-1]) List2.append(LIST[i]) i = i + 1 while not List2[len(List2)-1] == '@': List1.append(List2[len(List2)-1]) del(List2[len(List2)-1]) print List1 #逆ポーランド変換ここまで #ここから数字を計算する i,n = 0,len(List1)-1 List3 = [] #ここに計算結果が入る while i <= n: if re.findall("[0-9]+",List1[0]): List3.append(List1.pop(0)) elif List1[0] == '+': temp = int(List3.pop()) + int(List3.pop()) List3.append(temp) del(List1[0]) elif List1[0] == '-': temp = int(List3.pop(-2)) - int(List3.pop()) List3.append(temp) del(List1[0]) elif List1[0] == '*': temp = int(List3.pop()) * int(List3.pop()) List3.append(temp) del(List1[0]) elif List1[0] == '/': temp = int(List3.pop(-2)) / int(List3.pop()) List3.append(temp) del(List1[0]) i += 1 if len(List3) == 1 #1個だけの時はちゃんと計算ができた return List3
stringモジュールに変えてreモジュールを使えば、
>>> a = "(abc+de*f)" >>> b = re.findall("[a-z|A-Z]+", a) >>> b ['abc', 'de', 'f']
のようにうまくアルファベットのみを抽出できたし、こうすれば
>>> c = re.findall("[a-z|A-Z|0-9]+|[^a-z|A-Z|0-9]+", a) >>> c ['(', 'abc', '+', 'de', '*', 'f', ')']
これまたうまく変数になりそうなアルファベットと、その他の記号に分けることができた。これを使ってread_a_line関数をちょっと書き換える。
def read_a_line(list): #読み込んだ式をリストへ格納する import re temp = raw_input() inpt = re.findall("[a-z|A-Z|0-9]+|[^a-z|A-z|0-9]", temp) for i in inpt: list.append(i)
出力結果は
>>> reverse_polish()
Google + Microsoft
['Google', 'Microsoft', '+']
>>> reverse_polish()
12+(30-20)
['12', '30', '20', '-', '+']
[22]
>>> reverse_polish()
(324/2)*(42-21)+13
['324', '2', '/', '42', '21', '-', '*', '13', '+']
[3415]
あとは' = 'を使った式を上手に表現したり、変数に値を代入できたりすればいいんだけど・・・。さてどうしたもんだろうかな。ちっとも見当が付かねえな。