题目说明:
24点游戏是经典的纸牌益智游戏。
常见游戏规则:从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1), 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式。
解题思想:
- 生成4个符合要求的随机数
- 对4个随机数进行全排列
- 对‘+’、‘-’、‘×’、‘÷’进行全排列
- 通过拼凑的方式构造表达式
- 计算表达式,将满足运算结果为24的表达式打印出来
解题步骤:
1.生成4个符合要求的随机数
对于python来说,生成随机数一般都是通过导包来实现,在这里需要用到的包是random
random. randrange (stop) |
|
random. randrange (start, stop[, step]) |
Return a randomly selected element from range(start, stop, step) . |
random. randint (a, b) |
Return a random integer N such that a <= N <= b . |
我所用到的是random.
randint
(a, b)函数,使用它生成4个1-14的数字作为模拟抽取的卡牌
2.对4个随机数进行全排列
对随机数进行全排列可以使用python自带的包(itertools)或者自己写一个递归函数实现相同功能都可以,这里使用的是itertools进行随机数的全排列
递归实现全排列:https://blog.csdn.net/zhoufen12345/article/details/53560099
详细代码:
def generateNumberList(numbers):
result_list = []
count = 0
# set() 用于去除重复的排列,itertools.permutations()用于生成全排列的元组
for each_tuple in set(itertools.permutations(numbers, len(numbers))):
result_list.append(list(each_tuple))
count += 1
return result_list
3.对‘+’、‘-’、‘×’、‘÷’进行全排列
对4种运算符的全排列和数字的全排列几乎一样,但是因为是4个数字进行计算,所以只会用到3个运算符,所以在后期处理上只需要将最后一个运算符删除即可
详细代码:
def generateOperatorList(operators):
result_list = []
count = 0
# set() 用于去除重复的排列,itertools.permutations()用于生成全排列的元组
for each_tuple in set(itertools.permutations(operators, len(operators))):
templist = list(each_tuple)
templist.pop()
result_list.append(templist)
return result_list
4.通过拼凑的方式构造表达式
对生成的数字全排列列表和预算符全排列列表只需要交替的插入即可构造一个只有数字和“+、-、×、÷”的运算表达式,但这样构造的表达式不够多样,存在很多不满足运算结果等于24的情况,所以应当引入括号运算,保证运算的多样性。
在加入括号后可以尽可能多的产生满足计算结果等于24的表达式,但是也会出现很多相同的表达式
例如:
4+4+8+8=24
(4+4)+8+8=24
4+(4+8)+8=24
所以为了避免出现这样的情况,应当设置合适的条件来添加括号。如果一个表达式不是按照顺序计算的,那么在这个表达式中加入括号将有可能改变表达式最后的运算结果,为了避免加入括号后不能改变运算结果的情况,所以应当先判断改表达式在不添加括号的情况下结果是否等于24,否在添加括号
例如:
9+2×6+3=24
9+(2×6)+3=24
5.计算表达式,将满足运算结果为24的表达式打印出来
计算表达式可以通过两两计算得到结果再进行两两计算,但在python中提供了一种更加简单和快捷的计算表达式结果的方法
eval
(expression, globals=None, locals=None)
The arguments are a string and optional globals and locals. If provided, globals must be a dictionary. If provided, locals can be any mapping object.
在使用eval函数进行计算表达式时,有时会遇到表达式除数为0的情况,在python中这样的表达式是不合法的,程序会抛出异常导致整个代码的运行终止,为了避免这种情况,应当在有计算表达式的代码出添加异常处理机制,当程序抛出除数为0的异常时即使处理,使得整个代码能够继续运行完
详细代码(构造表达式+计算表达式):
def insertParentheses(number_list, operator_list):
count = 0
expression_list = []
for each_number_list in number_list:
for each_operator_list in operator_list:
expression1 = str(each_number_list[0]) + each_operator_list[0] + str(each_number_list[1]) \
+ each_operator_list[1] + str(each_number_list[2]) + each_operator_list[2] + \
str(each_number_list[3])
try:
result = eval(expression1)
except:
result = 0
if result == 24:
expression_list.append(expression1 + '=' + str(result))
count += 1
else:
expression2 = '(' + str(each_number_list[0]) + each_operator_list[0] + str(each_number_list[1]) + ')' \
+ each_operator_list[1] + str(each_number_list[2]) + each_operator_list[2] + \
str(each_number_list[3])
try:
result = eval(expression2)
except:
result = 0
if result == 24:
expression_list.append(expression2 + '=' + str(result))
count += 1
else:
expression3 = str(each_number_list[0]) + each_operator_list[0] + '(' + str(each_number_list[1]) \
+ each_operator_list[1] + str(each_number_list[2]) + ')' + each_operator_list[2] + \
str(each_number_list[3])
try:
result = eval(expression3)
except:
result = 0
if result == 24:
expression_list.append(expression3 + '=' + str(result))
count += 1
else:
expression4 = str(each_number_list[0]) + each_operator_list[0] + str(each_number_list[1]) \
+ each_operator_list[1] + '(' + str(each_number_list[2]) + each_operator_list[2] \
+ str(each_number_list[3]) + ')'
try:
result = eval(expression4)
except:
result = 0
if result == 24:
expression_list.append(expression4 + '=' + str(result))
count += 1
for each in expression_list:
print(each)
print('一共有%d个表达式' % count)
运行截图:
因为在处理时没有考虑位置而引起的重复,此处默认位置不同也是不同的表达式,如果想要去掉这种重复还请自行解决
源代码下载:https://download.csdn.net/download/xust_kevin/10702176