今天看到一个游戏,就是由电脑出一道题,然后游戏参与者来答题,最后电脑判断题是否做对了,题类型是这样的:请用以下四个数和加减乘除括号组成一个表达式,使结果等于多少多少。
比如:请用 9、9、4、5(每个数只能且必须使用一次),和 +、-、*、/、()(每个操作符可以使用0到多次)组成 24。
常见吧,现在我们就让电脑来判断,游戏参与者所组成的表达式是否正确。
第一步、看结果是否正确。
第二步、检查所使用的操作符、操作数是否有效。
第三步、检查是否所有的操作数都使用了。
方法不是最优,但是最好理解的。
怎么样,程序如下,使用类完成。
<%
class CNumberDoctor
'允许的操作符
'每个操作符可以无限使用
private operatorArr()
'允许的操作数
'二维数组
private operandArr()
'要组成的答案
dim answer
'================================================================================
'================================================================================
'重新设置操作符
'参数 c 为字符(串)类型
sub ResetOperator(c)
redim operatorArr(0)
operatorArr(0) = c
end sub
'增加一个操作符
'参数 c 为字符(串)类型
sub AddOperator(c)
dim ub
ub = UBound(operatorArr) + 1
redim preserve operatorArr(ub)
operatorArr(ub) = c
end sub
'重新设置操作数
'参数 n 为操作数,0-255 之间的整数有效
'参数 times 为允许该操作数使用的次数
sub ResetOperand(n, times)
redim OperandArr(1, 0)
OperandArr(0, 0) = n
OperandArr(1, 0) = times
end sub
'增加一个操作数
'参数 n 为操作数,0-255 之间的整数有效
'参数 times 为允许该操作数使用的次数
sub AddOperand(n, times)
dim ub
ub = UBound(OperandArr, 2) + 1
redim preserve OperandArr(1, ub)
OperandArr(0, ub) = n
OperandArr(1, ub) = times
end sub
'================================================================================
'================================================================================
'检查表达式
'参数 expression 为字符(串)类型
'表达式正确返回 true
'表达式错误返回 false
function ChckExpression(expression)
ChckExpression = true
on error resume next
'验证答案
if Eval(expression) <> answer then
ChckExpression = false
err.Clear
exit function
end if
'验证答案过程中是否有异常
if err.number <> 0 then
ChckExpression = false
err.Clear
exit function
end if
'验证所使用的操作符、操作数是否有效
dim i, c, str
for i = 1 to Len(expression)
c = Mid(expression, i, 1)
if IsOperator(c) then
if str <> "" then
if ValidOperand(str) then
str = ""
else
ChckExpression = false
exit for
end if
end if
else
str = str + c
end if
next
if str <> "" then
if ValidOperand(str) then
str = ""
else
ChckExpression = false
end if
end if
'检查是否所有的操作数都用完
if ChckExpression then
for i = 0 to UBound(operandArr, 2)
if operandArr(1, i) > 0 then
ChckExpression = false
exit for
end if
next
end if
end function
'检查 c 是否为允许的操作符
'参数 c 为字符(串)类型
'c 是操作符,返回 true
'c 不是操作符,返回 false
private function IsOperator(c)
IsOperator = false
dim i
for i = 0 to UBound(operatorArr)
if c = operatorArr(i) then
IsOperator = true
exit for
end if
next
end function
'验证 str 是否为有效操作数
'参数 str 为字符(串)类型
'在 operandArr 数组中找到与 str 对应的操作数时且可用数大于 0 时返回 true,否则返回 false
private function ValidOperand(str)
ValidOperand = false
on error resume next
dim n
n = CByte(str)
if err.number <> 0 then
err.Clear
exit function
end if
dim i
for i = 0 to UBound(operandArr, 2)
if operandArr(0,i)=n and operandArr(1,i)>0 then
ValidOperand = true
operandArr(1, i) = operandArr(1, i) - 1
exit for
end if
next
end function
end class
'================================================================================
'================================================================================
'示例
dim numberDoctor
set numberDoctor = new CNumberDoctor
'设置操作符
call numberDoctor.ResetOperator("+")
call numberDoctor.AddOperator("-")
call numberDoctor.AddOperator("*")
call numberDoctor.AddOperator("/")
call numberDoctor.AddOperator("(")
call numberDoctor.AddOperator(")")
'设置操作数,及每个操作数可使用的次数
call numberDoctor.ResetOperand(9, 1)
call numberDoctor.AddOperand(9, 1)
call numberDoctor.AddOperand(4, 1)
call numberDoctor.AddOperand(5, 1)
'设置答案
numberDoctor.answer = 24
'解题,如果正确会显示 True
response.write(numberDoctor.ChckExpression("(5+9/9)*4"))
set numberDoctor = nothing
%>