-
Question
即使只有 52 张牌,permutationIndex
我在其中描述的地方说明部分,将是一个巨大的数字;它是其中之一的数字52!
,需要29个字节来存储。
Thus 我不知道一个简单的方法来计算permutationIndex
一个很大的范围,并以最小的成本存储索引,或者也可以计算。我认为这个问题的解决方案将是三种算法:
计算正确的算法permutationIndex
to 实施Dealing
method
计算正确的算法permutationIndex
to 实施Collect
method
存储(或计算)的算法permutationIndex
以最小的成本
-
说明
我最初尝试实现一个整数句柄生成器范围从int.MinVale
to int.MaxValue
使用排列。
因为范围确实很大,所以我从实现开始a Dealer
有 52 张牌的类,实际上并不能存储一副牌像哈希集或数组,甚至不想随机(初始除外)。
对于给定的序数范围,我认为完整排列之一的每个序列都有一个索引,并将其命名为permutationIndex
。我使用索引来记住它是哪种排列,并且并不真正存储序列。该序列是一副牌的可能顺序之一。
And here is an example of emulation in animated graphics to show what I thought of.
每次我发牌时,我都会改变permutationIndex
and dealt
(发牌数),我知道哪些牌已发,哪些牌仍在手中。当我收回发出的牌时,我会知道牌号,并将其放在上面,它也成为下次发牌的牌。在动画中,colleted
is the 卡号.
欲了解更多信息,如下。
-
代码说明
概念样本Dealer
仅三个 3 的班级如下。
代码写在c# /questions/tagged/c%23,我也在考虑任何与语言无关 /questions/tagged/language-agnostic解决方案。
以下是示例代码的一些说明
用方法Dealing()
,我们得到一个number视为已发牌的牌的名称。它总是返回最右边数字(与数组相关),然后通过更改将其左侧的数字(即下一个可用的)滚动到最右边的位置permutationIndex
.
方法Collect(int)
用于收集发到的牌并将其放回牌堆中。
它会改变permutationIndex
另外,根据什么number卡被退回给经销商。
整数dealt
告诉我们已经发了多少张牌;来自最左边到存储在的计数dealt
已发牌。和permutationIndex
,我们知道牌的顺序。
The int[,]
示例代码中未使用数组,只是为了帮助想象排列。这switch语句被认为是用算法来实现的,该算法计算permutationIndex
.
The permutationIndex
与此答案中描述的内容相同
快速排列 -> 数字 -> 排列映射算法 https://stackoverflow.com/questions/1506078/fast-permutation-number-permutation-mapping-algorithms/1506337#1506337
-
示例代码
public static class Dealer {
public static void Collect(int number) {
if(1>dealt)
throw new IndexOutOfRangeException();
switch(permutationIndex) {
case 5:
case 0:
switch(number) {
case 3:
break;
case 2:
permutationIndex=1;
break;
case 1:
permutationIndex=4;
break;
}
break;
case 4:
case 3:
switch(number) {
case 3:
permutationIndex=5;
break;
case 2:
permutationIndex=2;
break;
case 1:
break;
}
break;
case 2:
case 1:
switch(number) {
case 3:
permutationIndex=0;
break;
case 2:
break;
case 1:
permutationIndex=3;
break;
}
break;
}
--dealt;
}
public static int Dealing() {
if(dealt>2)
throw new IndexOutOfRangeException();
var number=0;
switch(permutationIndex) {
case 5:
permutationIndex=3;
number=3;
break;
case 4:
permutationIndex=0;
number=1;
break;
case 3:
permutationIndex=1;
number=1;
break;
case 2:
permutationIndex=4;
number=2;
break;
case 1:
permutationIndex=5;
number=2;
break;
case 0:
permutationIndex=2;
number=3;
break;
}
++dealt;
return number;
}
static int[,] sample=
new[,] {
{ 1, 2, 3 }, // 0
{ 1, 3, 2 }, // 1
{ 3, 1, 2 }, // 2
{ 3, 2, 1 }, // 3
{ 2, 3, 1 }, // 4
{ 2, 1, 3 }, // 5
};
static int permutationIndex;
static int dealt;
}
不完全是您在这里想要完成的任务,但如果您想按照随机顺序处理一副牌,则可以使用洗牌算法。典型的shuffle算法是费希尔-耶茨 http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle。洗牌算法将创建一个数组,以随机顺序列出卡号(13,5,7,18,22,...等)。要进行处理,您从数组中的第一个元素开始并继续向前。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)