【问题标题】:Hashing every combination of tic tac toe table散列井字游戏表的每个组合
【发布时间】:2017-06-08 18:36:29
【问题描述】:

我正在研究一种算法来确定井字游戏模型是否有赢家。不过有一点点扭曲——函数has_won?被多次调用。因此,我正在阅读的书中算法问题的作者(Cracking the Coding Interview)建议生成 2^9 个可能的表中的每一个并将它们散列到一个表中。

为了为每个排列生成唯一的键,她将每个板表示为一个整数(板最初是一个 char 数组)。整数生成如下: (3^0)v0 + (3^1)v1 + (3^2)v2+...+(3^8)v8 如果空间为空,则 v 为 0,如果是 X,如果是 O,则为 2。

这就是我没有关注的内容。我明白她为什么要这么做。但是,如何保证在大约 20,000 个可能的板上不会有另一个板与该表示不共享相同的整数键值?她没有提供证据,我无法直观地理解为什么这是一个独特的数字。

【问题讨论】:

  • 有 3^9(不是 2^9)种可能的组合,给出 19683 种可能性(实际上更少,因为有些像 5x&2o 是不可能的,但是对于这个小数字,您不妨将它们全部包含并标记不可能的事情是没有胜利的)。一个普通的散列是完全没有必要的,因为你也可以只提供 19683 个桶来获得一个最小的完美散列。话虽如此,我不相信哈希是个好主意。最多只需要 8 个 if 语句(如果考虑到最后一步,则更少)来检查获胜者,散列板以提供密钥不太可能更快。
  • 这是一个 9 位、以 3 为底的数字。就像任何以 10 为底的整数都有唯一的二进制表示一样,任何以 3 为底的数字也是如此。

标签: algorithm data-structures hashtable


【解决方案1】:

让我们通过一个简单的例子来看看它是如何工作的。假设棋盘只有两个空格。我知道这不是一款好游戏,但作为第一步,使用它来展示数字代码的工作原理。在这种情况下,整数在您的符号中

(3^0)v0 + (3^1)v1

其中 v0 和 v1 告诉我们这两个空格是空的 (0) 有一个 X (1) 还是有一个 O (2)。现在列举案例:

_ _ (3^0) 0 + (3^1) 0 = 0
X _ (3^0) 1 + (3^1) 0 = 1
O _ (3^0) 2 + (3^1) 0 = 2

请注意,填充左侧空间只会生成小于 3 的数字。现在填充右侧空间。

_ X (3^0) 0 + (3^1) 1 = 3
_ O (3^0) 0 + (3^1) 2 = 6

请注意,在填充右侧空间时,我们只能得到三的倍数。现在做剩下的。

X X (3^0) 1 + (3^1) 1 = 4
O X (3^0) 2 + (3^1) 1 = 5
X O (3^0) 1 + (3^1) 2 = 7
O O (3^0) 2 + (3^1) 2 = 8

现在我们可以看到每个配置对应一个且只有一个整数。此外,我们可以通过整数除法得到整数的配置。以倒数第二个情况 7 为例。将其除以 3 得到 2,余数为 1。2 是右侧正方形的配置,1 是左侧的配置。这适用于上述所有示例。

如果您尝试使用两个以上的正方形,您将得到相同的结果。我知道这是真的的原因,并且你可以在你的帖子中获得你所要求的证明的方式是意识到一个以三为底的数字系统将每个正方形的状态保持在它的一个数字中。这就是您描述的编码的工作方式,这就是为什么整数编码中的每个项都具有 3 的幂。我认为这足以表明生成的整数是唯一的。

另一个可能的澄清是想象可以处于十种状态中的任何一种的正方形。调用这些 0 到 9。然后是任何普通的以十为底的数字,例如

234

在每个数字中保持一个且只有一个方格的状态,并且每个方格的配置都会为您提供一个且只有一个以十为基数的数字。用你在帖子中给出的符号写下这个数字

(10^0) 4 + (10^1) 3 + (10^2) 2 = 234

我们有 v0=4、v1=3 和 v2=2。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-18
    • 1970-01-01
    • 2015-06-12
    • 2015-01-08
    • 2013-04-26
    相关资源
    最近更新 更多