思路:
- 通过暴力方法破解(即全排列)
- 利用后缀表达式来去除括号的麻烦
- 对零这个特殊数字的处理
- 再后缀转中缀表达式
# 输入4个[1~13]之间的数字
def Input():
while True:
try:
a, b, c, d = map(int, input("请输入[1~13]之间的四个数字(空格分开):").split())
for i in [a, b, c, d]:
if i<1 or i>13:
raise ValueError("所输入的数字必须在[1~13]之间")
break
except Exception as result:
print("引发异常:", result)
return [a, b, c, d]
# 寻找所有符号的排列组合,所得结果是一个常量列表
def Queue_list(li_str):
queue = ['+', '-', '*', '/']
ans = []
while queue:
string = queue.pop(0)
if len(string)==3:
ans.append(string)
continue
for i in li_str:
queue.append(string+i)
return ans
# 利用回溯寻找出所有数字的排列组合
fuhao = Queue_list(['+', '-', '*', '/'])
def huisu(num, li, result):
if len(li)==4:
global fuhao
for each in fuhao:
for ans in func(li, each):
ans = check(ans)
result.append(ans)
# print("答案是:", ans)
for i in range(len(num)):
n = num.pop(i)
huisu(num, li+[n], result)
num.insert(i, n)
return result
# 对数字和符号进行排列组合,只用5种排列组合,直接列举
def collect(n, f):
ans = []
ans.append([n[0], n[1], f[0], n[2], f[1], n[3], f[2]])
ans.append([n[0], n[1], f[0], n[2], n[3], f[1], f[2]])
ans.append(n[0:3]+list(f[0:2])+[n[3]]+[f[2]])
ans.append(n[0:3]+[f[0]]+[n[3]]+list(f[1:]))
ans.append(n+list(f))
return ans
def func(nums, fuhao):
res = []
li_all = collect(nums, fuhao)
for each in li_all:
ans = kernel(each)
if -1<(24-ans)*1000<1:
res.append(each)
return res
# 核心代码
def kernel(li):
stack = []
for i in li:
if type(i)==type('string'):
b = stack.pop()
a = stack.pop()
if i=='+':
stack.append(a+b)
elif i=='-':
stack.append(a-b)
elif i=='*':
stack.append(a*b)
else:
if b==0:
return 0
stack.append(a/b)
else:
stack.append(i)
return stack[0]
# 后缀转中缀
def check(li):
stack = []
for i in li:
if type(i)==type('string') and len(i)==1:
b = str(stack.pop())
a = str(stack.pop())
temp = f'({a}{i}{b})'
stack.append(temp)
else:
stack.append(i)
return stack[0][1:-1]
def main():
num = Input()
result = huisu(num, [], [])
for ans in list(set(result)):
print("答案是:", ans)
main()