【问题标题】:Calculator Subtraction leads to infinite loop计算器减法导致无限循环
【发布时间】:2012-11-20 11:59:48
【问题描述】:

我正在开发一个可以接受用户输入的计算器。 它必须解决以下表达式:

1+38*(!2)-5%37

我一直在做加法和减法,但我遇到了一个问题。

我有一个循环正在寻找“+”或“-”符号。 对于“+”它有效,但对于“-”,每当我解决像

这样的表达式时

1-38

它让我进入一个无限循环,因为该表达式的结果是

-37

并且循环不断将“-”符号识别为减法,但将其识别为负数 37。

我该如何解决这个问题?

def symbols_exist(exp, symbols_list):
    """ Gets an expression string and a symbols list and returns true if any symbol
        exists in the expression, else returns false. """
    for s in symbols_list:
        if s in exp:
            return True
    return False

def BinaryOperation(exp, idx):
    """ Gets an expression and an index of an operator and returns a tuple with (first_value, operator, second_value). """
    first_value = 0
    second_value = 0

    #Get first value
    idx2 = idx -1
    while (idx2 > 0) and (exp[idx2] in string.digits):
        idx2 -=1

    first_value = exp[idx2:idx]

    #Get second value
    idx2 = idx +1
    while (idx2 < len(exp)) and (exp[idx2] in string.digits):
        idx2 += 1

    second_value = exp[idx+1:idx2]

    return (first_value, exp[idx], second_value)

def solve(exp):
    if not symbols_exist(exp, all_symbols):
        return exp

    idx = 0

    while idx < len(exp):
        if exp[idx] in string.digits:
            #Digit
            idx +=1
        elif exp[idx] in ("+", "-"):
            #Addition and Subtraction
            sub_exp = BinaryOperation(exp, idx)
            if sub_exp[1] == "+":
                value = int(sub_exp[0]) + int(sub_exp[2])
            else:
                value = int(sub_exp[0]) - int(sub_exp[2])

            value = str(value)

            exp = exp.replace(''.join(sub_exp), value)
            print exp

        return solve(exp)

【问题讨论】:

  • 您需要在此处发布一些代码以获得帮助
  • 在任何情况下我都无法让您的程序正常工作,但您不能只更改symbols_exist 以便在搜索符号之前删除任何初始- 吗? (例如if exp[0] == '-': exp = exp[1:])
  • 它确实有效,但最后一行(return solve(exp))需要取消缩进 1 个标签。

标签: python expression infinite-loop calculator


【解决方案1】:

结合原始示例中的三个功能的可能解决方案。 (编辑:刚刚意识到我发布的原始答案可以简化很多)

all_symbols = '+-'
def solve(expres):
    lhs, symbol, rhs = expres[0], None, ''
    for ch in expres[1:]:
        if symbol:
            rhs += ch
        elif ch in all_symbols:
            symbol = ch
        else:
            lhs += ch
    if symbol is '+':
        return int(lhs) + solve(rhs)
    if symbol is '-':
        return int(lhs) - solve(rhs)
    return int(expres)

print solve('1+5')

还有另一种可能有用的解决方案

operations = [
    ('+', lambda a, b: a + b),
    ('-', lambda a, b: a - b)
    ]
def solve(exp):
    for symbol, operation in operations:
        p = exp.rfind(symbol)
        if p > 0:
            return operation(solve(exp[:p]), solve(exp[p + 1:]))
    return int(exp)

【讨论】:

  • 我一直在尝试使用递归来做到这一点,这就是我设计不同功能的原因。我想要做的是解决表达式中的“最强”运算符,然后再次调用solve() 使用更新的表达式,其中将包含已解决的运算符(这是最强的,例如幂比乘法和乘法比加法或减法最强),
  • 并且递归将继续调用自身,直到所有表达式都变为没有任何符号的数字(这就是为什么solve()函数的基本条件是检查表达式中是否有更多符号)。
  • 这个建议也完全按照您描述的方式使用递归,并且可以适用于首先解决最强的运算符。无论哪种方式,您需要做的就是在检查表达式中的符号时忽略初始的“-”,此建议通过if ch in all_symbols and n: 实现,并查看我对您的问题的评论,了解如何在原始程序中执行相同操作。
猜你喜欢
  • 1970-01-01
  • 2020-12-09
  • 2017-05-02
  • 2020-01-20
  • 2020-08-27
  • 2021-05-07
  • 2012-08-24
  • 2020-11-16
相关资源
最近更新 更多