【问题标题】:How do you use a string to solve a math equation using python?如何使用字符串来使用 python 求解数学方程?
【发布时间】:2014-09-27 16:53:58
【问题描述】:

我正在尝试制作一个接受用户方程的 python 程序,例如:“168/24+8=11*3-16”,并尝试通过从用户输入中删除任意 2 个字符来使方程的两边彼此相等.这是我目前所拥有的:

def compute(side):
    val = int(side[0])
    x= val
    y=0
    z=None

    for i in range(1, len(side)-1):
        if side[i].isdigit():
                x= (x*10)+ int(side[i])
                if x == side[i].isdigit():
                    x= int(side[i])

        else:
            op = side[i]
            if op=="+":
                val += x
            elif op == "-":
                val -= x
            elif op == "*":
                val *= x
            else:
                val /=  x



    return print(val)

我已经编辑了我的计算函数。

def evaluate(e):

    side1 = ""
    side2 = ""
    equalsign = e.index("=")
    side1= e[:equalsign - 1]
    side2= e[:equalsign + 1]
    if compute (side1) == compute(side2):
        return True
    else:
        return False

def solve():

# use a for loop with in a for loop to compare all possible pairs
    pass

def main():

    e= input("Enter an equation: ")
    evaluate(e)

main()

对于实际的solve 函数,我想测试等式每一侧的所有可能对,并在删除每一对后检查等式是否等于另一侧。我正在考虑使用for 循环,它说:

    for i in side1:
        j= [:x]+[x+1:y]+[y+1:]
        if compute(j)==compute(side2):
            val= compute(j)    
            return val

我该怎么做呢?我对如何真正处理这个程序有点困惑。

【问题讨论】:

  • 我可以为此提供一些输入和预期输出吗?
  • 假设用户输入方程 168/24+8=11*3-16 程序检查一侧是否等于另一侧,15=17,因为它认为程序从用户输入使两边相等,18/2+8=11*3-16,因为 6 和 4 已被删除,所以等式现在等于 17=17
  • 呸!没有我想象的那么简单!

标签: python string-parsing python-3.4


【解决方案1】:

让我们开始讨论初步问题。

  • e = raw_input("Enter an equation: ") # input is fine if you are using Python3.x

  • side1 = e[:equalsign] #note that a[start:end] does not include a[end]

  • side2 = e[equalsign + 1:] # not e[:equalsign + 1].

  • val = int(side[0]) # not val = side[0] which will make val a string

  • 在操作部分,你在做val += side # or -= / *= / /= .. remember side is a string

编辑:

  1. 是的,我仍然坚持使用 Python 2.7(如果是 Python 3,请使用 input
  2. 要求解每一边的值,您可以简单地使用eval(side1) # or eval(side2)。使用eval 可能有其他选择。 (我自己是新手)。 eval 也将负责 PEMDAS。
  3. 添加了对side1 表达式的编辑。
  4. 更新了目前编写的代码。

    def compute(side):
    
        return eval(side)
    
    def evaluate(e):
    
        side1, side2 = e.split('=')
        if compute(side1) == compute(side2):
            return (True, e)
        else:
            return (False, 'Not Possible')
    
    def solve(e):
    
    
        for i in range(len(e)):  # loop through user input
            if e[i] in '=':  # you dont want to remove the equal sign
                continue
    
    
            for j in range(i+1, len(e)):  # loop from the next index, you dont want
    
                if e[j] in '=':           # to remove the same char
                    continue              # you dont want to remove '=' or operators
    
                new_exp = e[:i] + e[i+1:j] + e[j+1:]  # e[i] and e[j] are the removed chars
                #print e[i], e[j], new_exp             # this is the new expression    
    
                s1, s2 = new_exp.split('=')
    
                try:
                    if compute(s1) == compute(s2):
                        return (True, new_exp)
                except:
                    continue
        return (False, 'not possible')
    
    def main():
    
        e= raw_input("Enter an equation: ")
        print evaluate(e.replace(' ', ''))
    
    main()
    

这是我迄今为止提出的(至少适用于您的示例)。

  • 假设运算符不会被删除

最终编辑:根据@Chronical 的建议更新代码

  • 删除了每个循环中的 try-except 块,而是在计算每一边后才使用它

【讨论】:

  • 如果操作使用 python3 怎么办?
  • 我得到的是,我的操作是对一个字符串进行的,这就是我收到类型错误的原因。我不确定如何解决这个问题。
  • @PadraicCunningham,是的,编辑指出这一点。 @Cos 您可以简单地设置val = int(side[0]),这将确保val 的初始值是int
  • @Cos 您打算从用户输入中删除 2 个字符还是仅从 side1 中删除?我会根据你的回答,用我目前所想到的来更新主要答案。
  • 这2个字符可以从任何地方删除
【解决方案2】:

这是完全符合您要求的代码:

from itertools import combinations

def calc(term):
    try:
        return eval(term)
    except SyntaxError:
        return None

def check(e):
    sides = e.split("=")
    if len(sides) != 2:
        return False
    return calc(sides[0]) == calc(sides[1])

equation = "168/24+8 = 11*3-16".replace(" ", "")

for (a, b) in combinations(range(len(equation)), 2):
    equ = equation[:a] + equation[a+1:b] + equation[b+1:]
    if check(equ):
        print equ

核心技巧:

  • 使用eval() 进行评估。如果您将其用于任何用途,请注意此技巧的安全隐患。
  • 使用itertools.combinations 创建所有可能的要删除的字符对
  • 不要尝试太特别地处理= - 只需在check() 中捕获它

【讨论】:

  • 我从未使用过 intertools 并且想隐含地这样做我认为也应该允许删除运算符,除了等号。有什么想法吗?
  • • 你应该使用 itertools - 这就是你在 Python 中的做法。您可以查看 user54273 的答案,了解如何手动操作。但请记住:这不是蟒蛇式的做法。 • 我的代码已经删除了运算符。
猜你喜欢
  • 1970-01-01
  • 2021-06-21
  • 2019-10-23
  • 1970-01-01
  • 1970-01-01
  • 2016-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多