验证带有过多运算符的后缀

时间:2019-06-29 22:56:26

标签: python validation

我正在评估一个后缀表达式,我需要说的是,如果一个接一个的运算符太多,则无法对该表达式求值。我知道堆栈中没有任何内容,因此无法对其进行评估,但是我不知道如何在代码中添加它。

我仅在此处添加了我认为必要的代码。如果代码可以保持相对相似,那就太好了。

编辑:现在只是说什么都无法评估

def process(testline,count):
    k=[]

    for i in range(0,len(testline),1): 
        if(testline[i].isdigit() == True): 
            k.append(float(testline[i]))

        else:
            try:
                x = j.pop()
                y = j.pop()
            except IndexError:
                break

        if (testline[i]=='*'): 
            ans = x * y
            k.append(ans)

        elif (testline[i]=='+'):
            ans = x + y
            k.append(ans)

        elif (testline[i]=='-'):
            ans = x - y
            k.append(ans)

        elif (testline[i]=='/'):
            ans = x / y
            k.append(ans)

        else:
            print("Line",count,"is not able to be evaluated")
            return

    if len(k) != 1:
        print("Line",count,"is not able to be evaluated")
    else:
        print ('Line',count,'result is',k[0])
        return

    print('Line',count,'result is',k[0])

现在,输出为:

    Line 1 is not able to be evaluated
    Line 2 is not able to be evaluated
    Line 3 is not able to be evaluated
    Line 4 is not able to be evaluated

输入为:

    295+*3-
    61*7-4*
    61*79-15*
    6a*7-b*
    623-+*-1

3 个答案:

答案 0 :(得分:0)

您可以将pop移至迭代的开始并用try/except包围以检查是否可以弹出:

for i in range(0,len(testline),1): 
    if(testline[i].isdigit() == True): 
        k.append(float(testline[i]))

    else:
        try:
            x = k.pop()
            y = k.pop()
        except IndexError:
            break

        if (testline[i]=='*'): 
            ans = x * y
            k.append(ans)

        elif (testline[i]=='+'):
            ans = x + y
            k.append(ans)

        elif (testline[i]=='-'):
            ans = x - y
            k.append(ans)

        elif (testline[i]=='/'):
            ans = x / y
            k.append(ans)

        else:
            print("Line",count,"is not able to be evaluated")
            return

要使其更强大并且不需要添加额外的appends,我将这样做:

operators = {'*': lambda x ,y: x * y,
             '/': lambda x, y: x / y,
             '+': lambda x, y: x + y,
             '-': lambda x, y: x - y}

for c in testline:
    if c.isdigit(): 
        k.append(float(c))

    elif c in operators:
        try:
            x = k.pop()
            y = k.pop()
        except IndexError:
            break
        ans = operators[c](x, y)
        k.append(ans)

    else:
        print("Line",count,"is not able to be evaluated")
        return

编辑:更简单:

operators = {'*': lambda x ,y: x * y,
             '/': lambda x, y: x / y,
             '+': lambda x, y: x + y,
             '-': lambda x, y: x - y}

for c in testline:
    if c.isdigit(): 
        k.append(float(c))

    else:
        try:
            x = k.pop()
            y = k.pop()
            ans = operators[c](x, y)
            k.append(ans)
        except IndexError:  # Couldn't pop... (empty stack)
            break
        except KeyError:  # char is not a digit and not an operator
            print("Line",count,"is not able to be evaluated")
            return

答案 1 :(得分:0)

根据OP希望保持原始代码尽可能不变的愿望,这是该代码的版本,其更改最少。 OP所特别要求的主要更改是在每次算术运算之前添加检查以检查操作数是否不足。此代码在必要时还可以颠倒计算中的操作数顺序:

row = 0
while row < height:
    column = 0
    while column < width:
        if true_positives_mask[row][column] != 0:
            original_image[row][column] = constants.GREEN
        elif false_positives_mask[row][column] != 0:
            original_image[row][column] = constants.BLUE
        elif true_negatives_mask[row][column] != 0:
            original_image[row][column] = constants.RED
        column += 1
    row += 1

return original_image

使用此测试代码:

def process(testline,count):

    k=[]

    for i in range(0,len(testline),1):
        if(testline[i].isdigit() == True):
            k.append(float(testline[i]))

        elif (testline[i]=='*'):
            if len(k) < 2:
                print("Line", count, "is not able to be evaluated. not enough operands")
                return
            x = k.pop()
            y = k.pop()
            ans = x * y
            k.append(ans)

        elif (testline[i]=='+'):
            if len(k) < 2:
                print("Line", count, "is not able to be evaluated. not enough operands")
                return
            x = k.pop()
            y = k.pop()
            ans = x + y
            k.append(ans)

        elif (testline[i]=='-'):
            if len(k) < 2:
                print("Line", count, "is not able to be evaluated. not enough operands")
                return
            x = k.pop()
            y = k.pop()
            ans = y - x    # << reversed operands
            k.append(ans)

        elif (testline[i]=='/'):
            if len(k) < 2:
                print("Line", count, "is not able to be evaluated. not enough operands")
                return
            x = k.pop()
            y = k.pop()
            ans = y / x   # << reversed operands
            k.append(ans)

        else:
            print("Line",count,"is not able to be evaluated")
            return

    if len(k) != 1:
        print("Line",count,"is not able to be evaluated")
        return

    print('Line',count,'result is',k[0])

结果输出为:

lines = [
    '295+*3-',
    '61*7-4*',
    '61*79-15*',
    '6a*7-b*',
    '(-1)*2',
    '623-+*-1',
]

for i in range(len(lines)):
    process(lines[i], i + 1)

答案 2 :(得分:0)

这是我的版本,非常类似于@Tomrikoo的第二个版本,但提供了完整的答案并解决了原始代码的一些其他问题。该代码在所有情况下都将打印结果或错误,并在有效答案或无效堆栈条件(堆栈上有多个项目)的情况下处理最终状态。另外,我颠倒了操作数的应用顺序,使之正确(我假设'42 /'应该产生2而不是像我所有的HP计算器一样产生0.5):

def process(testline, count):

    operations = {
        '+': lambda x, y: y + x,
        '-': lambda x, y: y - x,
        '*': lambda x, y: y * x,
        '/': lambda x, y: y / x,
    }

    k = []

    for c in testline:

        if c.isdigit():
            k.append(float(c))

        elif c in operations:
            if len(k) < 2:
                print("Line {}: bad expression '{}' (not enough operands)".format(count, testline))
                return
            k.append(operations[c](k.pop(), k.pop()))

        else:
            print("Line {}: unexpected character '{}' in expression '{}'".format(count, c, testline))
            return

    if len(k) != 1:
        print("Line {}: bad expression '{}' (too many operands)".format(count, testline))
    else:
        print("Line {}: Result: '{}' = {}".format(count, testline, k[0]))


lines = [
    '295+*3-',
    '61*7-4*',
    '61*79-15*',
    '6a*7-b*',
    '(-1)*2',
    '623-+*-1',
]

for i in range(len(lines)):
    process(lines[i], i + 1)

输出:

Line 1: Result: '295+*3-' = 25.0
Line 2: Result: '61*7-4*' = -4.0
Line 3: bad expression '61*79-15*' (too many operands)
Line 4: unexpected character 'a' in expression '6a*7-b*'
Line 5: unexpected character '(' in expression '(-1)*2'
Line 6: bad expression '623-+*-1' (not enough operands)