# “24点”的算法分析

## 算法分析

### 分拆集合

 def enumerateAllSubsets(elements) : def appendElement(orig_subsets, element) : result = [] for set in orig_subsets : result.append(set) tmp = [] for ele in set : tmp.append(ele) tmp.append(element) result.append(tmp) return result result = [[]] for e in elements : result = appendElement(result, e) for e in result : e.sort() return result

enumerateAllSubsets所返回的子集集合并不能直接用于24点的计算，因此我们必须先做一些准备工作——去除空集和全集。由于集合中可能会有重复的数字，为了减少运算量，我们还要去除重复的子集。

 def getSets (elements): elements.sort() tmp_result = enumerateAllSubsets(elements) tmp_result.remove([]) tmp_result.remove(elements) result = [] for e in tmp_result : e.sort() try: result.index(e) except ValueError: result.append(e) return result

 def suppSet (fullSet, subSet): result = [] for item in fullSet : # 由于可能会有重复的元素，因此不能写 result.append(item) # for item in fullSet: for item in subSet : # if not item in subSet : result.remove(item) # result.append(item) return result

### 构造算式

 ADD = "+" MIN = "-" MUL = "*" DIV = "/" TYPE_OF_NUMBERS = (type(1), type(1.0)) class equationTree(object) : def __init__ (self, left_tree, operator=None, right_tree=None): self.left_tree = left_tree self.right_tree = right_tree self.operator = operator def value (self): if not self.operator : return float(self.left_tree) else: if type(self.left_tree) in TYPE_OF_NUMBERS: str_to_calc = str(float(self.left_tree)) else: str_to_calc = str(self.left_tree.value()) str_to_calc += self.operator if type(self.right_tree) in TYPE_OF_NUMBERS: str_to_calc += str(float(self.right_tree)) else: str_to_calc += str(self.right_tree.value()) try: ## 1. 出现 ZeroDivError的时候，这个算式的值就为None ## 2. 这要这个算式的某一部分的值为None，那么这个算式的值就是None result = eval(str_to_calc) except : result = None return result def __repr__ (self): if type(self.left_tree) in TYPE_OF_NUMBERS : left_repr = str(self.left_tree) else: left_repr = self.left_tree if type(self.right_tree) in TYPE_OF_NUMBERS : right_repr = str(self.right_tree) else: right_repr = self.right_tree if not self.operator : return left_repr else: if self.operator == ADD: pass elif self.operator == MIN: if type(self.right_tree) not in TYPE_OF_NUMBERS and self.right_tree.operator in (ADD, MIN): right_repr = "(" + right_repr + ")" elif self.operator == MUL: if type(self.left_tree) not in TYPE_OF_NUMBERS and self.left_tree.operator in (ADD, MIN) : left_repr = "(" + left_repr + ')' if type(self.right_tree) not in TYPE_OF_NUMBERS and self.right_tree.operator in (ADD, MIN): right_repr = "(" + right_repr +')' else: if type(self.right_tree) not in TYPE_OF_NUMBERS and self.right_tree.operator : right_repr = "(" + right_repr + ')' if type(self.left_tree) not in TYPE_OF_NUMBERS and (self.left_tree.operator in (ADD, MIN)): left_repr = "(" + left_repr + ')' return left_repr + self.operator + right_repr

### 枚举算式

 def getEqTrees (elements): if len(elements) == 1 : return [equationTree(elements[0])] elif len(elements) == 2: return [equationTree(elements[0], ADD, elements[1]), equationTree(elements[0], MIN, elements[1]), equationTree(elements[0], MUL, elements[1]), equationTree(elements[0], DIV, elements[1]), equationTree(elements[1], MIN, elements[0]), equationTree(elements[1], DIV, elements[0]),] else: result = [] for e in getSets(elements): for left_tree in getEqTrees(e) : for right_tree in getEqTrees(suppSet(elements, e)) : for op in (ADD, MIN, MUL, DIV) : result.append(equationTree(left_tree, op, right_tree)) return result

## 结尾

 if __name__ == '__main__' : print """ Written by shhgs, on March 3, 2004.""" result = [] print """ Please input a tuple of integer, delimited by colon. For example: 1, 2, 3, 4 Don't try to input more than 5 numbers, otherwise it will take a long long time to respond. Four is recommended. """ tup = input('Please input the tuple of integers: ') for eq in getEqTrees(list(tup)): if eq.value() == 24 : result.append(eq) print "%s = 24" % eq

[1]这个算法是用Python实现的，因此这里用Python的表示方法。有兴趣的读者可以试着用Java或其他语言来实现。

[2]这个程序里面有中文注释，所以运行的时候会出现警告。要想解决这个问题，可以在程序的第一行加上：

 # -*- coding: mbcs -*-

• 本文已收录于以下专栏：

## 关于24点游戏的编程思路与基本算法

24点游戏的算法，其中最主要的思想就是穷举法。所谓穷举法就是列出4个数字加减乘除的各种可能性，包括括号的算法。我们可以将表达式分成以下几种：首先我们将4个数设为a，b，c，d，，其中算术符号有+，-，...
• wangqiulin123456
• 2012年11月04日 13:25
• 41731

## 24点算法

//24点算法，思想就是表达式树，4个数字，3个符号只能建成两种树 一开始初始化a数组为4个数字，初始化b数组为符号,然后用两种树进行运算，如果符合输出即可 但需要注意括号的位置，但表达式树处理...
• fengsigaoju
• 2016年03月01日 12:34
• 979

## 计算24点程序代码

• xyisv
• 2017年01月24日 17:23
• 2194

## 经典二十四点程序算法

• smartboysboys
• 2014年03月08日 09:47
• 2856

## java实现24点算法

• u014282557
• 2017年04月27日 15:40
• 1885

## 24点经典算法

1、概述　　给定4个整数，其中每个数字只能使用一次；任意使用 + - * / ( ) ，构造出一个表达式，使得最终结果为24，这就是常见的算24点的游戏。这方面的程序很多，一般都是穷举求解。本文介绍一...
• mingWar
• 2008年11月29日 19:11
• 23018

## 24点游戏算法

24点游戏算法 现在我们在做一个24点的小游戏，我主要负责算法部分,前面有章博客已经讲解了加括号的四则表达式的计算算法，现在要解决就是24点的算法。 24点游戏的说明： 54张牌去掉...
• luoweifu
• 2013年09月11日 19:49
• 28493

## 24点小游戏算法

• Tong_jy
• 2017年01月26日 13:13
• 246

## C++实现24点游戏算法

**2017-7-18更新更新内容： 算法本身并没问题，些许小地方有bug，已经修改。如果测试还有问题，请评论告知，非常感谢！！现已上传github： 这里写链接内容#include #inclu...
• qq_16013649
• 2015年09月24日 11:39
• 2618

## 算24点 算法经典 回溯法

• 2010年05月04日 13:48
• 711B
• 下载

举报原因： 您举报文章：“24点”的算法分析 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)