プロが教えるわが家の防犯対策術!

 プログラミングの勉強をしながら式入力型の電卓を作りたいと思い調べたところ「逆ポーランド法」を知りました。
 まず四則演算出来るものを作り最終的には関数電卓を目指そうと思っているのですが、この「逆ポーランド法」を取り入れた計算プログラムを学べば良いのでしょうか?もっと適している他の手法はありますか?
公開されている式入力型の電卓ソフトはどのような手法でプログラムされているのでしょうか?(なかなか式入力型のサンプルが見つからなくて…。)
 言語はActiveBasicを使用していますが、情報が少ない為VisualBasicのサイトで勉強しています。
宜しくお願いいたします。

A 回答 (5件)

逆ポーランド記法は、式の解析が簡単なので、作りやすいかもしれませんね。


逆ポーランド記法を解するする処理ルーチンを作って、一般入力式を逆ポーランド記法に変換するルーチンを作って渡しても良いと思いますが、四則演算くらいなら、構文解析やりつつ計算するのもそれほどは難しくはないです。
サンプルとしてVBで四則演算を理解して計算する関数を書いてみました
参考にしてみて下さい。
'"(3+5)*7-2"の様な文字列で与えられた式を計算する
Public Function calc(ByVal str As String) As Double
Const STACKSIZE = 3
Dim cstack(STACKSIZE) As String, csp As Integer '演算子スタック
Dim vstack(STACKSIZE) As Double, vsp As Integer '値スタック
Dim level As Integer
Dim sign As Integer, frac As Double
Dim wk As Double, cwk As String, c
Dim buff As String
Dim pos As Integer

str = Replace(str, " ", "") '式からスペースを取り除く
vsp = STACKSIZE
csp = STACKSIZE
csp = csp - 1 'スタックは使う前に-1する
cstack(csp) = "@" 'empty mark
wk = 0: sign = 0: frac = 10
For pos = 1 To Len(str) '一文字ずつ走査する
c = Mid(str, pos, 1) '現在着目している文字
If "0" <= c And c <= "9" Then '数字
If sign = 0 Then sign = 1
If frac = 10 Then
wk = wk * frac + Val(c)
Else
wk = wk + Val(c) * frac
frac = frac / 10
End If
Else
If c = "." Then '小数点
If frac < 1 Then
MsgBox "小数点が2つ以上ある"
calc = 0
Exit Function
Else
frac = 1 / 10
End If
Else '数ではない
If sign <> 0 Then '初めの時は積まない、例えば-で始まる数の時
vsp = vsp - 1
vstack(vsp) = sign * wk
End If
wk = 0: sign = 0: frac = 10 '数の初期化
If c = "-" Then '符号のマイナスの処理
If pos = 1 Then '最初にマイナス符号があれば符号
sign = -1
GoTo nextLoop
Else
If InStr("(*/-+)", Mid(str, pos - 1, 1)) > 0 Then 'マイナス符号の前が演算子の時符号
sign = -1
GoTo nextLoop
End If
End If
End If
Select Case c
Case "*", "/"
cwk = cstack(csp) '直前の演算子を取り出す
If cwk = "@" Or cwk = "+" Or cwk = "-" Then '現在の演算子が優先である
csp = csp - 1
cstack(csp) = c
Else
If cwk = "*" Then '掛け算する
vstack(vsp + 1) = vstack(vsp + 1) * vstack(vsp)
Else
If cwk = "/" Then '割り算する
vstack(vsp + 1) = vstack(vsp + 1) / vstack(vsp)
End If
End If
vsp = vsp + 1
cstack(csp) = c
End If
Case "-", "+"
cwk = cstack(csp)
If cwk = "@" Then
csp = csp - 1
cstack(csp) = c
Else
Select Case cwk
Case "+"
vstack(vsp + 1) = vstack(vsp + 1) + vstack(vsp)
Case "-"
vstack(vsp + 1) = vstack(vsp + 1) - vstack(vsp)
Case "*"
vstack(vsp + 1) = vstack(vsp + 1) * vstack(vsp)
Case "/"
vstack(vsp + 1) = vstack(vsp + 1) / vstack(vsp)
End Select
vsp = vsp + 1
cstack(csp) = c
End If
Case "(" 'カッコ中身でcalcを呼び出す
pos = pos + 1
level = 1 'カッコの組の数
sign = 1
buff = ""
Do While pos <= Len(str)
c = Mid(str, pos, 1)
If c = ")" Then
level = level - 1
If level = 0 Then
wk = calc(buff)
Exit Do
End If
Else
If c = "(" Then level = level + 1
End If
buff = buff & c
pos = pos + 1
Loop
If level > 0 Then 'カッコの数が合っていない時
wk = calc(buff)
pos = pos - 1
End If
Case ")" 'ありえないはず
MsgBox ("閉じカッコが多すぎる")
Case Else
MsgBox (c & "は使用できない文字です")
End Select
End If
End If
nextLoop:
Next
vsp = vsp - 1
vstack(vsp) = sign * wk
cwk = cstack(csp)
Do Until "@" = cwk
Select Case cwk
Case "+"
vstack(vsp + 1) = vstack(vsp + 1) + vstack(vsp)
Case "-"
vstack(vsp + 1) = vstack(vsp + 1) - vstack(vsp)
Case "*"
vstack(vsp + 1) = vstack(vsp + 1) * vstack(vsp)
Case "/"
vstack(vsp + 1) = vstack(vsp + 1) / vstack(vsp)
End Select
vsp = vsp + 1
csp = csp + 1
cwk = cstack(csp)
Loop
calc = vstack(vsp)
End Function
    • good
    • 0

訂正の訂正


If InStr("(*/-+", Mid(str, pos - 1, 1)) > 0 Then
    • good
    • 0
この回答へのお礼

BLUEPIXYさんサンプルまで乗せて頂きありがとうございます。とても参考になります。

お礼日時:2005/01/14 08:35

If InStr("(*/-+)", Mid(str, pos - 1, 1)) > 0 Then


の部分を
If InStr("*/-+", Mid(str, pos - 1, 1)) > 0 Then
に修正して下さい。
    • good
    • 0

#2ですが、バグってますね。


カッコが複数ある時に、なんかうまく行かないみたいです。
恥ずかしい。(>_<)
    • good
    • 0

逆ポーランド法を用いて電卓の作成は当然できますよ


でも、VECTORなどで公開されている電卓ソフトは逆ポーランド法ではなく、独自の手法だと思います

逆ポーランド法はスタック(PUSH/POP)を使うのでVBなら配列でやると思いますのでREDIMを使えば大丈夫でしょう
    • good
    • 0
この回答へのお礼

独自ですか…、私にはまだまだ無理ですので出来ることからやっていこうと思います。
ありがとうございました。

お礼日時:2005/01/13 19:20

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!