判断游戏者组成的表达式是否正确

作者:chilleen 来源:ITPOW(原创) 日期:2006-2-23

今天看到一个游戏,就是由电脑出一道题,然后游戏参与者来答题,最后电脑判断题是否做对了,题类型是这样的:请用以下四个数和加减乘除括号组成一个表达式,使结果等于多少多少。

比如:请用 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
%>
相关文章