2014-09-27 362 views
1

我想制作一个采用用户等式的python程序,例如:“168/24+8=11*3-16”,并尝试通过从用户输入中删除任何2个字符来使等式两边相等。这是我到目前为止:如何使用字符串来解决使用python的数学公式?

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 

我该如何去做这件事?我对如何真正处理这个程序感到困惑。

+0

我可以有一些组输入和预期产出的呢? – 2014-09-27 17:04:27

+0

可以说用户输入等式168/24 + 8 = 11 * 3-16程序检查一边是否等于另一边,15 = 17,因为该程序从用户输入中删除2个字符,所以两边都是等于,18/2 + 8 = 11 * 3-16,因为6和4已经被移除,所以现在的等式等于17 = 17 – Cos 2014-09-27 17:25:34

+0

唷!并不像我想的那么简单! – 2014-09-27 17:32:28

回答

2

让我们来看看初步问题。

  • 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版(使用input如果Python 3)
  2. 为了解决每一方的价值,你可以简单地将你se 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块在每个循环,而不是仅仅在计算每一边后使用它
+0

如果操作系统使用python3会怎么样? – 2014-09-27 17:28:21

+0

我得到的是我的操作正在做一个字符串,这就是为什么我得到一个类型错误。我不确定如何解决这个问题。 – Cos 2014-09-27 17:31:20

+0

@PadraicCunningham,耶编辑指出。 @Cos你可以简单地设置'val = int(side [0])',这将确保'val'的初始值是一个'int'。 – 2014-09-27 17:33:49

1

这里是代码,它完全符合你的要求:

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()
+0

我从来没有使用过intertools,并且希望隐式地做到这一点,我认为应该允许删除运算符,除了等号。有任何想法吗? – Cos 2014-09-27 20:26:00

+0

•你应该使用itertools - 这就是你如何在Python中完成的。您可以查看user54273的答案,了解如何手动执行此操作。但请记住:这不是执行它的pythonic方式。 •我的代码已经删除了操作员。 – Chronial 2014-09-28 10:47:37