即使只有52张卡片(我在“说明”部分中描述的
permutationIndex
)也将是一个庞大的数字;它是52!
之一中的数字,需要29个字节来存储。因此,我不知道一种简单的方法来计算很大范围的
permutationIndex
,并以最小的成本存储索引,或者也许也可以计算出它。我在想这个问题的解决方案是三种算法:permutationIndex
到的算法将实现Dealing
方法permutationIndex
到的算法将实现Collect
方法permutationIndex
的算法 我最初尝试使用置换来实现范围从
int.MinVale
到int.MaxValue
的整数句柄生成器。因为范围真的很大,所以我从实现到一个带有52张卡的
Dealer
类开始,该类实际上并没有存储像哈希集或数组这样的一副卡,甚至也不需要随机的(首字母除外) 。在给定范围的序数范围内,我认为完整排列之一的每个序列都有一个索引,并将其命名为
permutationIndex
。我使用索引来记住它是哪个排列,而不真正存储序列。该顺序是一副纸牌的可能顺序之一。这是一个在动画图形中进行仿真的示例,以展示我的想法。
每次我发牌时,我都会更改
permutationIndex
和dealt
(已发牌数),从而知道哪些发了牌,哪些仍在手。当我取回已发行的卡时,我会知道卡号并将其放在最上面,它也成为下次处理的卡。在动画中,colleted
是卡号。 有关更多信息,如下。
仅三个3的概念样本
Dealer
类如下。该代码是用c#编写的,我也正在考虑任何language-agnostic解决方案。
这是示例代码的一些描述
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;
}
最佳答案
不完全是您要在此处完成的任务,但是,如果您想随机抽取一副纸牌来进行交易,则可以使用随机播放算法。典型的随机播放算法是Fisher-Yates。随机播放算法将创建一个以随机顺序列出卡号的数组(13,5,7,18,22,...等)。为了解决这个问题,您从数组中的第一个元素开始,然后继续前进。