|
|
|
2016/3/9(Wed) 10:44:39|NO.74834
閲覧、ありがとうございます!
現在、入力した文字列を読み取り計算するツールを作成している途中です。
細かい問題は残るものの形にはしたのですが、機構部分に無駄な処理が多くないかと不安です。
もしよろしければ、改善案やアドバイスを頂けると嬉しいです。
初めての書き込みなので、
書き込みに問題があればお手数ですが教えていただけると嬉しいです!
作成途中のため、
・負の乗算
・0での除算
・負以外の符号、演算子を先頭に入力する
・小数点以下は切り捨て
など、問題に対応する処理が施されていないので、実行する場合は気をつけてください。
以下はソースです。ご一読ありがとうございます!
// 変数に見立てたモノ
repeat 100
p.cnt = cnt
loop
color : boxf
color 255, 255, 255
font "メイリオ"
objmode 2
sdim 文字列
文字列 = "1+2-3*4/5-2*2*2"
座標X = 12
座標Y = 18
pos 座標X, 座標Y
Input 文字列, 640 -座標X * 2
objsize 640 -座標X * 2
button "計算", *計算
座標Y += ginfo_cy
stop
*計算
color : boxf
color 255, 255, 255
pos 座標X, 座標Y
文字列C = 文字列
mes 文字列
// 変数の置換
repeat 100
変数 = "p" + cnt
strrep 文字列C, 変数, str(p.cnt)
loop
// 演算
repeat
文字列S = 文字列C
算出 = 0
// 演算子の置換
strrep 文字列S, "*", "S"
strrep 文字列S, "/", "S"
strrep 文字列S, "+", "T"
strrep 文字列S, "-", "T"
文字列D = 文字列S
strrep 文字列D, "F", " "
strrep 文字列D, "S", " "
strrep 文字列D, "T", " "
sdim 演算子番号
演算子座標 = 0
// 演算子座標の割り出し
repeat
演算子番号.cnt = instr(文字列D, 演算子座標, " ")
if 演算子番号.cnt = -1 : break
演算子番号.cnt += 演算子座標
演算子座標 = 演算子番号.cnt + 1
loop
if 演算子番号 = -1 : break
if 演算子番号 = 0 & 演算子番号.1 = -1 : break
// 演算
演算 = instr(文字列S, 0, "F")
if 演算 = -1 {
演算 = instr(文字列S, 0, "S")
if 演算 = -1 : 演算 = instr(文字列S, 0, "T")
}
if 演算子番号 = 0 : 演算 = 演算子番号.1
repeat
if 演算子番号.cnt = -1 : break
if 演算子番号.cnt != 演算 : continue
if cnt = 0 {
左辺位置 = 0
} else {
左辺位置 = 演算子番号.(cnt -1) + 1
}
if 演算子番号.(cnt + 1) = -1 {
右辺位置 = 演算 + 5
} else {
右辺位置 = 演算子番号.(cnt + 1)
}
演算子 = strmid(文字列C, 演算, 1)
演算式 = strmid(文字列C, 左辺位置, 右辺位置 -左辺位置)
title ""+文字列C
split 演算式, 演算子, 左辺, 右辺
if 演算子 = "*" : 算出 = int(左辺) * int(右辺)
if 演算子 = "/" : 算出 = int(左辺) / int(右辺)
if 演算子 = "+" : 算出 = int(左辺) + int(右辺)
if 演算子 = "-" : 算出 = int(左辺) - int(右辺)
if 演算子 = "-" & 演算子番号 = 0 : 算出 = 0 - int(左辺) - int(右辺) : 算出 * -1
strrep 文字列C, 演算式, str(算出)
loop
await 1
loop
mes "=" + 文字列C
| |
|
2016/3/9(Wed) 16:04:46|NO.74836
特に問題ないかと。
>kanamaruさん
作成途中のため、小数点以下は切り捨てで、問題に対応する処理が施されていないそうです。
|
|
2016/3/9(Wed) 16:08:26|NO.74837
>kanamaruさん
ご指摘とURL、ありがとうございます!
自身での使用は切り捨てでも問題はなかったのでint型で作成してしまいましたが、
やはり正確なのにこしたことはありませんからね! 頑張ってみようと思います!
|
|
2016/3/9(Wed) 16:39:54|NO.74838
そのモジュールはわたしがかいたのですが(そのときの名前はNoaでした)そのモジュールは確か動作が少しおかしかったのと、あまりにもきたないスクリプトなので、参考にはできればしてほしくないです。
整数と実数、どちらで計算するか切りかえられたらいいなとおもいました。
|
|
2016/3/10(Thu) 08:59:25|NO.74845
皆さん書き込みありがとうございます!
無駄な処理がないと言われ、安心して書き続けることができました。
汎用性の面から処理をモジュールに変え、
初めに書き込んだ問題点の修正。加えて、括弧の実装に至りました!
double型にも対応し、
型を変更すれば、実数・小数点以下切り捨ての切り替え可能です。
いくつか問題が見つかるかもしれませんが、
致命的なものはないと思われるので、解決とします。
ご協力ありがとうございました!
また困り事で書き込むかもしれませんが、その時もどうかよろしくお願いします。
以下はソースです。ご一読ありがとうございます!
// モジュール領域
#module
// 文字列計算
#deffunc 文字列計算 str 式, val 解
代入式 = 式
// 括弧判定
repeat
括弧左 = instr(代入式, 0, "(")
if 括弧左 != -1 {
括弧右 = instr(代入式, (括弧左 + 1), ")")
if 括弧右 = -1 : dialog "括弧が閉じられていません。" : 解 = 0 : return
括弧右 += 括弧左
括弧内 = strmid(代入式, (括弧左 + 1), (括弧右 -括弧左))
括弧式 = 代入式
括弧演算式 = "(" + 括弧内 + ")"
文字列計算 括弧内, 括弧解
strrep 括弧式, 括弧演算式 , str(括弧解)
代入式 = 括弧式
continue
}
break
loop
// 演算子の追加
strrep 代入式, "*", "*+"
strrep 代入式, "/", "/+"
strrep 代入式, "+-", "-"
strrep 代入式, "--", "+"
// 演算
repeat
// 演算子の置換
評価 = 代入式
strrep 評価, "*", "A"
strrep 評価, "/", "A"
strrep 評価, "+", "B"
strrep 評価, "-", "B"
位置 = 評価
strrep 位置, "A", " "
strrep 位置, "B", " "
// 演算子位置の割り出し
dim 演算子位置
演算子位置 = instr(位置, 0, " ")
if 演算子位置 != 0 : 代入式 = "+" + 代入式 : continue
repeat
if cnt = 0 : 演算子位置 = 0 : continue
演算子位置.cnt = instr(位置, (演算子位置.(cnt -1) + 1), " ")
if 演算子位置.cnt = -1 : break
演算子位置.cnt += 演算子位置.(cnt -1) + 1
loop
// 乗除の演算
対象位置 = instr(評価, 0, "A")
if 対象位置 != -1 : {
repeat
if 演算子位置.cnt = -1 : break
if 演算子位置.cnt != 対象位置 : continue
if cnt = 0 {
左辺位置 = 0
} else {
左辺位置 = 演算子位置.(cnt -1)
}
if 演算子位置.(cnt + 2) = -1 {
右辺位置 = 対象位置 + 65536
} else {
右辺位置 = 演算子位置.(cnt + 2)
}
演算子 = strmid(代入式, 対象位置, 1)
演算式 = strmid(代入式, 左辺位置, 右辺位置 -左辺位置)
split 演算式, 演算子, 左辺, 右辺
if 演算子 = "*" : 解 = double(左辺) * double(右辺)
if 演算子 = "/" {
if 右辺 = "+0" : dialog "0で除算しました。" : 解 = 0 : return
解 = double(左辺) / double(右辺)
}
解 = "+" + 解
strrep 解, "+-", "-"
strrep 代入式, 演算式, 解
loop
continue
}
解 = double(代入式)
if 演算子位置.1 = -1 : break
// 加減の演算
左辺 = strmid(代入式, 演算子位置, 演算子位置.1 -演算子位置)
if 演算子位置.2 = -1 {
右辺 = strmid(代入式, 演算子位置.1, 演算子位置.1 +65536)
} else {
右辺 = strmid(代入式, 演算子位置.1, 演算子位置.2 -演算子位置.1)
}
解 = double(左辺) + double(右辺)
解 = "+" + 解
strrep 解, "+-", "-"
演算式 = 左辺 + 右辺
strrep 代入式, 演算式, 解
await
loop
return
// グローバル領域
#global
sdim 式
objsize 640
式 = "-2+(2.32+5)*2+(2+2)/4"
input 式
button "演算", *演算
stop
*演算
color 255, 255, 255
boxf : color
pos ,50
文字列計算 式, 解
mes 式
mes "=" + int(解)
mes "=" + double(解)
| |
|