加括号问题

Ealisman 2009-05-25 09:27:28
四则运算 加括号问题:只要支持一个括号即可

现在我给出没有加括号的四则运算代码! 请大侠帮忙修改!
谢谢!

代码如下:
string ls_text,ls_temp,ls_parm[]
dec ldc_result
Long ll_beg = 1,ll_pos,i,j = 1,k = 1,ll_len
long ll_temp

ls_text = Trim(sle_1.text)
ll_len = Len(ls_text)
For i = 1 To UpperBound(ls_parm[])
SetNull(ls_parm[i])
Next

For i = 1 To ll_len
ls_temp = Mid(ls_text,i,1)
ll_temp = ASC(ls_temp)
If (ll_temp <> 42) and (ll_temp <> 43) and (ll_temp <> 45) and (ll_temp <> 47) and (ll_temp <> 46) And Not Isnumber(ls_temp) Then
MessageBox('ERROR',"请输入正确字符") //若不是“运算符”和“数值”就报错
Return
End If
Next

for i = 1 To ll_len
ls_temp = Mid(ls_text,i,1)
If Isnumber(ls_text) Then ls_parm[j] = ls_text

Choose Case ls_temp
Case '+'
ll_pos = Pos(ls_text,'+',1)
If ll_pos > 0 Then
ls_parm[j] = Left(ls_text,ll_pos - 1) //定位到运算符“+”的左边一位
j++
ls_parm[j] = Mid(ls_text,ll_pos,1)
j++
ls_text = Mid(ls_text,ll_pos + 1,Len(ls_text) - ll_pos)
i = 0
End If
Case '-'
ll_pos = Pos(ls_text,'-',1)
If ll_pos > 0 Then
ls_parm[j] = Left(ls_text,ll_pos - 1)
j++
ls_parm[j] = Mid(ls_text,ll_pos,1)
j++
ls_text = Mid(ls_text,ll_pos + 1,Len(ls_text) - ll_pos)
i = 0
End If
Case '*'
ll_pos = Pos(ls_text,'*',1)
If ll_pos > 0 Then
ls_parm[j] = Left(ls_text,ll_pos - 1)
j++
ls_parm[j] = Mid(ls_text,ll_pos,1)
j++
ls_text = Mid(ls_text,ll_pos + 1,Len(ls_text) - ll_pos)
i = 0
End If
Case '/'
ll_pos = Pos(ls_text,'/',1)
If ll_pos > 0 Then
ls_parm[j] = Left(ls_text,ll_pos - 1)
j++
ls_parm[j] = Mid(ls_text,ll_pos,1)
j++
ls_text = Mid(ls_text,ll_pos + 1,Len(ls_text) - ll_pos)
i = 0
End If
End Choose
Next

If Not IsNumber(ls_parm[1]) Or Not IsNumber(ls_parm[UpperBound(ls_parm[])]) Then
MessageBox('ERROR',"算式未完成")
return
End If

For i = 1 To UpperBound(ls_parm[])
If ls_parm[i] = '/' Then
If i = UpperBound(ls_parm[]) Then Exit
If Dec(ls_parm[i + 1]) = 0 then
MessageBox('提示','被除数不可以为0')
Return
End if
End If
IF Mod(i, 2) = 0 THEN
ll_temp = Asc(ls_parm[i])
IF (ll_temp <> 42) and (ll_temp <> 43) and (ll_temp <> 45) and (ll_temp <> 47) THEN
MessageBox('ERROR',"请输入正确运算符")
return
end if
End if
IF Mod(i, 2) = 1 THEN //判断奇偶
ll_temp = Asc(ls_parm[i])
IF Not IsNumber(String(ll_temp)) THEN
MessageBox('ERROR',"请输入正确数字")
return
end if
End if
Next

wf_multi(ls_parm[])
wf_divide(ls_parm[])
wf_add_sub(ls_parm[])

For i = 1 To UpperBound(ls_parm[])
messagebox("Result",ls_parm[i])
Next


几个函数:
1.wf_add_sub(ls_parm[]) 如下:
Long i,j,ll_pos = 0
String ls_temp
String ls_parm[]

For i = 1 To UpperBound(as_parm[])
ls_temp = as_parm[i]
If ls_temp = '+' Then
ll_pos = i
Exit
End If
If ls_temp = '-' Then
ll_pos = i
Exit
End If
Next
If ll_pos < 1 Then Return
If ls_temp = '+' Then
as_parm[ll_pos - 1] = String(Dec(as_parm[ll_pos - 1]) + Dec(as_parm[ll_pos + 1]))
ElseIf ls_temp = '-' Then
as_parm[ll_pos - 1] = String(Dec(as_parm[ll_pos - 1]) - Dec(as_parm[ll_pos + 1]))
End If

For i = 1 To UpperBound(as_parm[]) - ll_pos - 1
as_parm[ll_pos + i - 1] = as_parm[ll_pos + i + 1]
Next

For i = UpperBound(as_parm[]) To UpperBound(as_parm[]) - 1 step -1
SetNull(as_parm[i])
Next

wf_add_sub(as_parm[])


2.wf_divide(ls_parm[]) 函数如下:
Long i,j,ll_pos = 0
String ls_temp
String ls_parm[]

For i = 1 To UpperBound(as_parm[])
ls_temp = as_parm[i]
If ls_temp = '/' Then
ll_pos = i
Exit
End If
Next
If ll_pos < 1 Then Return
as_parm[ll_pos - 1] = String(Round(Dec(as_parm[ll_pos - 1]) / Dec(as_parm[ll_pos + 1]),2))


For i = 1 To UpperBound(as_parm[]) - ll_pos - 1
as_parm[ll_pos + i - 1] = as_parm[ll_pos + i + 1]
Next

For i = UpperBound(as_parm[]) To UpperBound(as_parm[]) - 1 step -1
SetNull(as_parm[i])
Next

wf_divide(as_parm[])


3.wf_multi(as_parm[]) 函数如下:
Long i,j,ll_pos = 0
String ls_temp
String ls_parm[]

For i = 1 To UpperBound(as_parm[])
ls_temp = as_parm[i]
If ls_temp = '*' Then
ll_pos = i
Exit
End If
Next
If ll_pos < 1 Then Return
as_parm[ll_pos - 1] = String(Dec(as_parm[ll_pos - 1]) * Dec(as_parm[ll_pos + 1]))
For i = 1 To UpperBound(as_parm[]) - ll_pos - 1
as_parm[ll_pos + i - 1] = as_parm[ll_pos + i + 1]
Next

For i = UpperBound(as_parm[]) To UpperBound(as_parm[]) - 1 step -1
SetNull(as_parm[i])
Next

wf_multi(as_parm[])


...全文
126 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
做梦的猫 2009-06-03
  • 打赏
  • 举报
回复
正宗的 pb 脚本,本人原创!
winter0991 2009-06-03
  • 打赏
  • 举报
回复
好像是C
Ealisman 2009-06-02
  • 打赏
  • 举报
回复
请问你这是PB语言吗?
还是C#?
做梦的猫 2009-05-27
  • 打赏
  • 举报
回复
接上...


//语法转换
count = 0
ls_buf = ""
li_length = Len(as_expressions)

for n_loop = 1 to li_length + 1
lc_result = Mid(as_expressions, n_loop, 1)
if (IsNumber(lc_result)) or (lc_result = ".") or (lc_result = "-") then
if lc_result = '-' then
row = 0
do
row ++
lc_result = Mid(as_expressions, n_loop - row, 1)
loop while (lc_result = "(") or (lc_result = ")")

if not IsNumber(lc_result) then
ls_buf += "-"
else
if ls_buf <> "" then
count ++
ld_object[count] = Double(ls_buf)
ls_expressions += "|" + String(count) + "|"
ls_buf = ""
end if
ls_expressions += "-"
end if
else
ls_buf += String(lc_result)
end if

else
if ls_buf <> "" then
count ++
ld_object[count] = Double(ls_buf)
ls_expressions += "|" + String(count) + "|"
ls_buf = ""
end if
ls_expressions += String(lc_result)
end if
next


//messagebox("转换后的语法",ls_expressions)
//count = upperbound(ld_object)
//for n_loop = 1 to count
// messagebox("运算对象栈的实际值",string(ld_object[n_loop]))
//next
//return ''



//按算符优先法进行计算
ls_char_stack = "{"
ls_expressions += "}"

rowcount = ad_preference.RowCount()
if rowCount = 0 then
MessageBox("错误", "算术运算符优先权表未载入!")
return ""
end if

count = 0

do
count ++
//1
ls_a = Mid(ls_expressions, count, 1)
//2
if ls_a = "|" then
rtu = Pos(ls_expressions, "|", count + 1)
ls_object_stack += Mid(ls_expressions, count, rtu - count + 1)
count += rtu - count
// messagebox("运算对象进栈",ls_object_stack)//
continue
end if
//3
do
ls_o = Right(ls_char_stack, 1)
lb_exit = false
if Pos(ls_char, ls_a) > 0 then
if ls_a = "}" then ls_a = "{" //因优先表的起始、终止标识符不同于运算符,故临时交换
column_no = ad_preference.Find("row = '" + ls_a + "'", 1, rowcount)
if ls_a = "{" then ls_a = "}"

if column_no > 0 then
column_no ++
row = ad_preference.Find("row = '" + ls_o + "'", 1, rowcount)
lc_result = ad_preference.GetItemString(row, column_no)
choose case lc_result
case "<" //3.1
ls_char_stack += ls_a
lb_exit = true
case "=" //3.2
ls_char_stack = Left(ls_char_stack, Len(ls_char_stack) - 1)
lb_exit = true
case ">" //3.3
ls_buf = ""
do
ls_object_stack = Left(ls_object_stack, Len(ls_object_stack) - 1)
ls_buf2 = Right(ls_object_stack, 1)

if ls_buf2 = "|" then
ls_object_stack = Left(ls_object_stack, Len(ls_object_stack) - 1)
else
ls_buf += ls_buf2
end if
loop while ls_buf2 <> "|"
ls_buf = Reverse(ls_buf)
n_loop = Integer(ls_buf)
ld_1 = ld_object[n_loop]
// messagebox("第 1 次从栈中取运算对象",ld_1)//

ls_buf = ""
do
ls_object_stack = Left(ls_object_stack, Len(ls_object_stack) - 1)
ls_buf2 = Right(ls_object_stack, 1)

if ls_buf2 = "|" then
ls_object_stack = Left(ls_object_stack, Len(ls_object_stack) - 1)
else
ls_buf += ls_buf2
end if
loop while ls_buf2 <> "|"
ls_buf = Reverse(ls_buf)
n_loop = Integer(ls_buf)
ld_2 = ld_object[n_loop]
// messagebox('第 2 次从栈中取运算对象',ld_2)//

rtu = UpperBound(ld_object)
choose case ls_o
case "+"
ld_object[rtu + 1] = ld_2 + ld_1
ls_object_stack += "|" + String(rtu + 1) + "|"
case "-"
ld_object[rtu + 1] = ld_2 - ld_1
ls_object_stack += "|" + String(rtu + 1) + "|"
case "*"
ld_object[rtu + 1] = ld_2 * ld_1
ls_object_stack += "|" + String(rtu + 1) + "|"
case "/"
if ld_1 = 0 then
MessageBox("信息", "0 不能作除数")
return ""
end if

ld_object[rtu + 1] = ld_2 / ld_1
ls_object_stack += "|" + String(rtu + 1) + "|"
case "^"
ld_object[rtu + 1] = f_square(ld_2, ld_1)
ls_object_stack += "|" + String(rtu + 1) + "|"
end choose
// messagebox("运算后的结果",ld_object[rtu + 1])//

ls_char_stack = Left(ls_char_stack, Len(ls_char_stack) - 1)
case "?"
if (ls_o = "(") or (ls_o = ")") then
MessageBox("括号不匹配", ls_o)
else
MessageBox("括号不匹配", ls_a)
end if
return ""
end choose
end if
else
MessageBox("无效的运算符", ls_a)
return ""
end if
loop while not lb_exit
loop while ls_a <> "}"

rtu = UpperBound(ld_object)
if rtu = 0 then return ""


return String(ld_object[rtu])
做梦的猫 2009-05-27
  • 打赏
  • 举报
回复
计算函数 f_Clac(readonly string, datastore)

/*
1. 从输入串中读入一个符号至 a;
2. 如果 a 是运算对象,那么把它压入运算对象栈,然后转至步骤 (1);
3. 如果 a 是运算符,那么与当前运算符栈顶符 o 比较优先性:
3.1 若 a>o,那么将 a 压入运算符栈,然后转至步骤 (1);
3.2 若 a=o,那么或者从运算符栈中弹出 o,废弃 a 符号;或者结束分析过程;
3.3 若 a<o,栈中为句柄,可以进行归约,那么应作关于 o 的语义处理,即生成关于 o 的
运算目标指令。用 o 运算后的结果替换运算对象栈中的栈顶符号和栈次顶符号,并且从运
算符栈中弹出栈顶符号,然后转至步骤 (3) 继续处理;
3.4 若 a 与 o 不存在优先关系,那么意味着输入串中含有错误,此时应作错误处理。
参数:
as_expressions: 表达式
ad_preference: 优先权表
*/

string ls_buf,ls_buf2,ls_char,ls_expressions
string ls_object_stack,ls_char_stack
string ls_a,ls_o
char lc_result
long count,n_loop,row,rowcount,column_no,li_length,rtu
double ld_object[]
double ld_1,ld_2,ld_buf
boolean lb_exit


ls_char = "+-*/^(){}" //有效运算符

//基本语法检查
ls_buf = as_expressions


// ")" 左边不应该有运算符
rtu = 0
ls_buf2 = "+-*/^"
do
rtu = Pos(ls_buf, ")", rtu + 1)
if rtu > 0 then
if Pos(ls_buf2, Mid(ls_buf, rtu - 1, 1)) > 0 then
MessageBox("无效的表达式1", Mid(ls_buf, rtu - 1, 1) + Mid(ls_buf, rtu,

1))
return ""
end if
end if
loop while rtu > 0

// "}" 左边不应该有运算符
rtu = 0
ls_buf2 = "+-*/^"
do
rtu = Pos(ls_buf, "}", rtu + 1)
if rtu > 0 then
if Pos(ls_buf2, Mid(ls_buf, rtu - 1, 1)) > 0 then
MessageBox("无效的表达式2", Mid(ls_buf, rtu - 1, 1) + Mid(ls_buf, rtu,

1))
return ""
end if
end if
loop while rtu > 0

// "(" 右边不应该有运算符;"-" 除外
rtu = 0
ls_buf2 = "+*/^"
do
rtu = Pos(ls_buf, "(", rtu + 1)
if rtu > 0 then
if Pos(ls_buf2, Mid(ls_buf, rtu + 1, 1)) > 0 then
MessageBox("无效的表达式3", Mid(ls_buf, rtu, 1) + Mid(ls_buf, rtu + 1,

1))
return ""
end if
end if
loop while rtu > 0

// "{" 右边不应该有运算符;"-" 除外
rtu = 0
ls_buf2 = "+*/^"
do
rtu = Pos(ls_buf, "{", rtu + 1)
if rtu > 0 then
if Pos(ls_buf2, Mid(ls_buf, rtu + 1, 1)) > 0 then
MessageBox("无效的表达式4", Mid(ls_buf, rtu, 1) + Mid(ls_buf, rtu + 1,

1))
return ""
end if
end if
loop while rtu > 0


do
rtu = Pos(ls_buf, "(")
if rtu > 0 then ls_buf = Replace(ls_buf, rtu, 1, "")
loop while rtu > 0
do
rtu = Pos(ls_buf, ")")
if rtu > 0 then ls_buf = Replace(ls_buf, rtu, 1, "")
loop while rtu > 0

li_length = Len(ls_buf)

// 运算符两边不应该再有运算符(除括号);"-" 号要特殊处理
for n_loop = 1 to li_length
if Pos(ls_char, Mid(ls_buf, n_loop, 1)) > 0 then
lc_result = Mid(ls_buf, n_loop, 1)

if lc_result = "-" then
if Pos(ls_char, Mid(ls_buf, n_loop - 1, 1)) > 0 then
if n_loop > 2 then // 用 2 的原因是考虑到负数;如 1+-1
lc_result = Mid(ls_buf, n_loop - 2, 1)
else
lc_result = ""
end if
else
if n_loop > 1 then
lc_result = Mid(ls_buf, n_loop - 1, 1)
else
lc_result = ""
end if
end if

if (not IsNumber(lc_result)) and (lc_result <> ".") and (lc_result <> "")

then
MessageBox("无效的表达式5", Mid(ls_buf, n_loop - 1, 1) + Mid

(ls_buf, n_loop, 1))
return ""
end if

if Pos(ls_char, Mid(ls_buf, n_loop + 1, 1)) > 0 then
if n_loop + 2 <= li_length then
lc_result = Mid(ls_buf, n_loop + 2, 1)
else
lc_result = ""
end if
else
if n_loop + 1 <= li_length then
lc_result = Mid(ls_buf, n_loop + 1, 1)
else
lc_result = ""
end if
end if

if (not IsNumber(lc_result)) and (lc_result <> ".") then
MessageBox("无效的表达式6", Mid(ls_buf, n_loop, 1) + Mid(ls_buf,

n_loop + 1, 1))
return ""
end if
else //if lc_result = '-' then
lc_result = Mid(ls_buf, n_loop - 1, 1)
if (not IsNumber(lc_result)) and (lc_result <> ".") then
MessageBox("无效的表达式7", Mid(ls_buf, n_loop - 1, 1) + Mid

(ls_buf, n_loop, 1))
return ""
end if

lc_result = Mid(ls_buf, n_loop + 1, 1)
if lc_result = "-" then
lc_result = Mid(ls_buf, n_loop + 2, 1)

if (not IsNumber(lc_result)) and (lc_result <> ".") then
MessageBox("无效的表达式8", Mid(ls_buf, n_loop, 1) + Mid

(ls_buf, n_loop + 1, 1))
return ""
end if
else
if (not IsNumber(lc_result)) and (lc_result <> ".") then
MessageBox("无效的表达式9", Mid(ls_buf, n_loop, 1) + Mid

(ls_buf, n_loop + 1, 1))
return ""
end if
end if
end if
end if
next

做梦的猫 2009-05-27
  • 打赏
  • 举报
回复
复杂的有啊,不过,还得做个外部数据窗口 d_clac 配合一下:

/* 运算符优先权表,数据类型全部为 string, 1
row plus minus ride divide square l_bracket r_bracket end
+ > > < < < > < >
- > > < < < > < >
* > > > > < > < >
/ > > > > < > < >
( < < < < < = < ?
) > > > > ? > > >
^ > > > > < > > >
{ < < < < < ? < =
*/
wag_enu 2009-05-26
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 lzp_lrp 的回复:]
string ls_exp

ls_exp = '20*12+23+15+(20-12)*2'

messagebox('', dw_1.describe(evaluate(ls_exp, 1)))

即可
[/Quote]

同意,但是应该是 messagebox('', string(dw_1.describe("evaluate('"+ls_exp+"', 0)")) )
Ealisman 2009-05-26
  • 打赏
  • 举报
回复
版主,您好!

你的这么简单? 不会吧? 我的朋友们都被难住了!

不可能这么简化的啊!
WorldMobile 2009-05-25
  • 打赏
  • 举报
回复
string ls_exp

ls_exp = '20*12+23+15+(20-12)*2'

messagebox('', dw_1.describe(evaluate(ls_exp, 1)))

即可

740

社区成员

发帖
与我相关
我的任务
社区描述
PowerBuilder 脚本语言
社区管理员
  • 脚本语言社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧