由于我是Python初学者,我试图从一些网站学习一些代码。我在GitHub中找到了一个为算术表达式执行Bruteforce search的算法。代码是:
#!python
import operator
import itertools
from fractions import Fraction
operations = dict()
operations['+'] = operator.add
operations['-'] = operator.sub
operations['/'] = operator.truediv
operations['*'] = operator.mul
def solve(target, numbers):
"""List ways to make target from numbers."""
numbers = [Fraction(x) for x in numbers]
return solve_inner(target, numbers)
def solve_inner(target, numbers):
if len(numbers) == 1:
if numbers[0] == target:
yield str(target)
return
# combine a pair of numbers with an operation, then recurse
for a,b in itertools.permutations(numbers, 2):
for symbol, operation in operations.items():
try:
product = operation(a,b)
except ZeroDivisionError:
continue
subnumbers = list(numbers)
subnumbers.remove(a)
subnumbers.remove(b)
subnumbers.append(product)
for solution in solve_inner(target, subnumbers):
# expand product (but only once)
yield solution.replace(str(product), "({0}{1}{2})".format(a, symbol, b), 1)
if __name__ == "__main__":
numbers = [1, 5, 6, 7]
target = 5
solutions = solve(target, numbers)
for solution in solutions:
print("{0}={1}".format(target, solution))
它只是使用我的numbers
结束尝试任何算术表达式,然后打印得到target
的结果(我得到的结果)。
我想知道,当表达式没有target
我设置的结果时,如何打印脚本尝试的任何解决方案?
编辑:
这是我尝试过的代码:
#!python
import operator
import itertools
from fractions import Fraction
operations = dict()
operations['+'] = operator.add
operations['-'] = operator.sub
operations['/'] = operator.truediv
operations['*'] = operator.mul
def solve(target, numbers):
"""List ways to make target from numbers."""
numbers = [Fraction(x) for x in numbers]
return solve_inner(target, numbers)
def solve_inner(target, numbers):
if len(numbers) == 1:
num = numbers[0]
yield str(num), num == target
return
# combine a pair of numbers with an operation, then recurse
for a,b in itertools.permutations(numbers, 2):
for symbol, operation in operations.items():
try:
product = operation(a,b)
except ZeroDivisionError:
continue
subnumbers = list(numbers)
subnumbers.remove(a)
subnumbers.remove(b)
subnumbers.append(product)
for solution, truth in solve_inner(target, subnumbers):
yield solution.replace(str(product),
"{0}=({1}{2}{3})".format(product, a, symbol, b), 1), truth
if __name__ == "__main__":
numbers = [1, 5, 6, 7]
target = 5
solutions = solve(target, numbers)
for solution, truth in solutions:
print("{0}? {1}".format(solution,
'True' if truth else ''))
我得到了实际的产品,但我得到了表达式中小操作的结果:
42=(7*6)/5=(42/5)=(1*42/5)
虽然我实际上只想在字符串的开头只获得42个。
答案 0 :(得分:2)
如果num [0]等于target,则递归通过产生str(num [0])而终止,否则无效。如果产生了某些东西,则字符串表达式建立在连续的产量上。要获得所有表达式,必须始终产生一些东西。我还选择是否达到目标。相反,可以在打印之前评估表达式。
#!python
import operator
import itertools
from fractions import Fraction
operations = dict()
operations['+'] = operator.add
operations['-'] = operator.sub
operations['/'] = operator.truediv
operations['*'] = operator.mul
def solve(target, numbers):
"""List ways to make target from numbers."""
numbers = [Fraction(x) for x in numbers]
return solve_inner(target, numbers)
def solve_inner(target, numbers):
if len(numbers) == 1:
num = numbers[0]
yield str(num), num == target
return
# combine a pair of numbers with an operation, then recurse
for a,b in itertools.permutations(numbers, 2):
for symbol, operation in operations.items():
try:
product = operation(a,b)
except ZeroDivisionError:
continue
subnumbers = list(numbers)
subnumbers.remove(a)
subnumbers.remove(b)
subnumbers.append(product)
for solution, truth in solve_inner(target, subnumbers):
# expand product (but only once)
yield solution.replace(str(product),
"({0}{1}{2})".format(a, symbol, b), 1), truth
if __name__ == "__main__":
numbers = [1, 5, 6, 7]
target = 5
solutions = solve(target, numbers)
for solution, truth in solutions:
print("{0}={1}? {2}".format(target, solution,
'True' if truth else ''))
原版中有一个小故障。产品附加到最后,但替换了与前面产品匹配的第一个数字。我相信结果可能是表达式的遗漏,在这种情况下算法并不完整。由于无法在最后开始更换,因此应将产品放在前面(subnumbers.insert(0, product)
),以便更换产品。我会让你试验一下它的不同之处。但我相信如果写得正确,代码会更容易理解。