使此函数采用任意长度的字符串

时间:2016-05-04 21:41:20

标签: python python-3.x

此函数采用一串数字和一个目标整数,并打印所有可能的方法来插入运算符以达到所需目标。在所有情况下,输出必须按顺序包含所有数字;没有可以省略。

#!/usr/bin/env python3

def find_expressions(digits, target):
    if not (isinstance(digits, str) or isinstance(digits, list)) or not isinstance(target, int):
        raise TypeError
    if len(digits) != 5:
        raise TypeError('digits must be of length 5')
    solutions = []
    operators = ('', ' + ', ' - ', ' * ', ' / ')
    for i in operators:
        for j in operators:
            for k in operators:
                for l in operators:
                    s = digits[0] + i + digits[1] + j + digits[2] + k + digits[3] + l + digits[4]
                    try:
                        if eval(s) == target:
                            solutions.append(s + ' == {}'.format(target))
                    except (ZeroDivisionError, SyntaxError):
                        pass
    print('\n'.join(solutions))

它不漂亮,但它有效。问题是它只需要长度为5的字符串。如何才能使它成为任意长度的字符串? (例如,调用find_expressions('12345678', 2)应该是有效的。)我认为我需要用递归替换for循环,但是我不知道如何实现这一点。

示例输出

调用find_expressions('75228', 5)打印:

7 + 5 + 2 / 2 - 8 == 5
7 * 5 - 22 - 8 == 5
7 * 5 - 2 - 28 == 5

买者

我对通过循环所有可能性而采取的整个蛮力方法感到不满意。如果总体上有更好的算法,我想听听它。 然而,这个问题是关于使这个函数采取任意长度的输入,同时做出尽可能小的改变。

2 个答案:

答案 0 :(得分:5)

使用itertools.product

console.log(JSON.stringify(Deck));

答案 1 :(得分:1)

诀窍是获得序列+-*/的所有可能的排列 - 包括重复项,因此第一个序列需要++++;其长度应为len(digits)-1,因为对于 n 位数,您需要n - 1个运算符。

排列总数为operators ** positions;也就是说,每个操作员都可以出现在每个位置。我没有看到任何实际测试所有可能性的方便快捷方式。

以下内容基于Get all 4-character combinations of a given alphabet;如果没有数字的插入和启用# print ..行,您将看到它显示整个列表。

如果您的输入可能是字符串,也可能不是字符串,请使用str(digits[x]),这样字符串连接就不会是barf。

以下代码

def find_expressions(digits, target):
    if not (isinstance(digits, str) or isinstance(digits, list)) or not isinstance(target, int):
        raise TypeError
    solutions = []
    operators = ('', ' + ', ' - ', ' * ', ' / ')
    used = [0] * (len(digits)-1)
    for i in range(len(operators)**(len(digits)-1)):
      attempt = str(digits[0])
      for j in range(1,len(digits)):
        attempt += operators[used[j-1]] + str(digits[j])
        # print (operators[used[j-1]], end="")
      # print ()
      for j in range(len(digits)-1):
        used[j] += 1
        if used[j] >= len(operators):
          used[j] = 0
        else:
          break

      try:
        if eval(attempt) == target:
          print (attempt, '==', eval(attempt))
      except (ZeroDivisionError, SyntaxError):
        pass

find_expressions ([7,5,2,2,8], 5)

显示

7 * 5 - 2 - 28 == 5
7 * 5 - 22 - 8 == 5
7 + 5 + 2 / 2 - 8 == 5.0

(最后一个打印为float,因为/使它成为了)。