我一直在考虑使用Python快速评估手牌。 在我看来,加快处理速度的一种方法是将所有牌面和西服表示为素数,然后将它们相乘以表示手牌。 白衣:
class PokerCard:
faces = '23456789TJQKA'
suits = 'cdhs'
facePrimes = [11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 53, 59, 61]
suitPrimes = [2, 3, 5, 7]
和
def HashVal(self):
return PokerCard.facePrimes[self.cardFace] * PokerCard.suitPrimes[self.cardSuit]
这将为每只手提供一个数值,通过模可以告诉我手中有多少个国王或多少个心。 例如,任何有五个或更多球杆的手都会平均除以2 ^ 5; 任何有四个国王的手都会平均除以59 ^ 4,依此类推。
问题在于,像AcAdAhAsKdKhKs这样的七张牌手的散列值约为62.7万亿次,这将需要超过32位才能在内部进行表示。 有没有一种方法可以在Python中存储如此大的数字,从而允许我对其执行算术运算?
您确定一旦开始以这种方式表示数据,您仍然会看到速度上的显着提高吗? 我知道这不能回答您的问题,但仍然..
我有一个建议:我建议使用字典,而不是对卡的值和表示使用单独的变量。 (因此,面孔= {2:11,3:13,4:17,5:19,6:23,7:29,8:31,9:37,T:41,J:43,Q:53,K :59,A:61}和西服= {c:2,d:3,h:5,s:7}。)
Python支持" bignum"整数类型,该整数类型可以处理任意大数。在Python 2.5+中,此类型称为long,并且与int类型分开,但是解释器将自动使用更合适的那个。在Python 3.0+中,int类型已被完全删除。
不过,这只是实现细节-只要您拥有2.5版或更高版本,就只需执行标准数学运算,并且任何超出32位数学界限的数字都将自动(透明地)转换为bignum。
您可以在PEP 0237中找到所有血腥细节。
问题是,使用bignum而不是32位整数对性能造成的影响是否超过了使用智能手评估方法带来的性能优势。
实际上,int和long之间的障碍已被打破2.5。 3.0完全删除了int,使long成为唯一的整数类型。
@Ignacio —没错,Id将2.5和3.0的更改混为一谈。修正了我的答案。
一个大数字有多大?可以是PHI ^ 4000000吗?
@Mike Caron —如果PEP 0237中列出的结构正确,则long的长度(以数字表示)将存储为无符号的32位整数,最多4,294,967,295位,这意味着它们可以轻松保存φ**(4 * 10 * * 6),仅832,951位。但是,φ不是整数,因此您需要使用Decimal(Pythons浮点数bignum)来计算数字。但是,您可以随后将结果存储在long中。
@ IgnacioVazquez-Abrams只是需要澄清的一点,long是3.0中唯一的整数类型,但其名为int。 (并且旧的int消失了。)
python自然支持任意大整数:
例:
>>> 10**1000 100000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000
例如,您甚至可以得到一个巨大的整数值fib(4000000)。
但是它仍然(暂时)不支持任意大的浮点数!
如果您需要一个大的,大的,浮动的,然后检查十进制模块。在这些论坛上有一些使用示例:OverflowError:(34,结果太大)
另一个参考:http://docs.python.org/2/library/decimal.html
如果需要提高速度,甚至可以使用gmpy模块(这可能是您感兴趣的):在代码中处理大数
另一种参考:https://code.google.com/p/gmpy/
您可以这样做很有趣,但除此之外,这不是一个好主意。它不会加快我能想到的任何速度。
拿到手中的卡将是一个整数分解操作,这比访问数组要昂贵得多。
添加卡将是乘法运算,而删除卡是除法运算,这两个字都是大型的多字数字,这比在列表中添加或删除元素要昂贵得多。
手的实际数字值不会告诉您任何信息。您需要分解素数,并按照扑克规则比较两只手。对于这样的手,h1
python自然支持任意大整数:
In [1]: 59**3*61**4*2*3*5*7*3*5*7
Out[1]: 62702371781194950
In [2]: _ % 61**4
Out[2]: 0