如何在不存储卡片的情况下实施经销商类别?

Ken*_*Kin 6 c# language-agnostic algorithm math permutation

  • 即使只有52张牌,permutationIndex我在" 解释"部分中描述的位置也是一个很大的数字; 它是一个数字52!,需要29个字节才能存储.

    因此,我不知道计算permutationIndex大范围的简单方法,并以最小成本存储索引,或者也可以计算.我在想这个问题的解决方案是三种算法:

    1. 其计算正确的算法permutationIndex实现Dealing方法

    2. 其计算正确的算法permutationIndex实现Collect方法

    3. 以最小成本存储(或计算)的算法permutationIndex

  • 说明

    我本来试图实现一个整数手柄发生器从一系列int.MinValeint.MaxValue使用排列.

    因为范围真的很大,所以我从实现开始一个Dealer52卡的类,它实际上不存储像hashset或数组的卡片,甚至不想随机(初始除外).

    对于给定范围的序数,我认为其中一个完整排列的每个序列都有一个索引,并将其命名permutationIndex.我使用索引来记住它是哪个排列而不是真正存储序列.序列是卡片组的可能顺序之一.

    这里有一个动画图形模拟示例,以显示我的想法. 在此输入图像描述

    每次我发卡时,我都会更改permutationIndexdealt(发卡的数量),我知道哪些卡是那些卡,哪些卡还在手中.当我收回发回的卡片时,我会知道卡片号码,并将其放在顶部,它也会成为下次处理的卡片.在动画中,colleted卡号.


有关更多信息,请按以下步骤

  • 代码说明

    Dealer仅有三个3的概念样本类如下.代码是用编写的,我也在考虑任何与解决方案.

    以下是示例代码的一些描述

    • 通过这种方法Dealing(),我们获得了许多处理的卡片.它总是返回最右边的数字(与数组相关),然后通过更改将其左边的数字(比如下一个可用的数字)滚动到最右边的位置permutationIndex.

    • 该方法Collect(int)用于收集并将处理后的卡片放回到卡座中.permutationIndex根据卡片返还给经销商的数量,它也会改变.

    • 整数表示dealt我们处理了多少张牌; 从最左边到存储的数量dealt都是发卡.有了permutationIndex,我们知道卡的顺序.

    • int[,]不使用示例代码中的数组,只是为了帮助设想排列.所述开关语句被认为与计算用于算法来实现permutationIndex.

    • permutationIndex是这个答案的描述同样的事情,
      快速置换- >数字- >置换映射算法

  • 示例代码

    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;
    }
    
    Run Code Online (Sandbox Code Playgroud)

Ser*_*nov 1

如果我没理解错的话,下面的代码可以实现这一点:

public class Dealer {
    public int Dealing() {
        var number=
            _freeCards.Count>0
                ?_freeCards.Dequeue()
                :_lastNumber++;

        _dealtCards.Add(number);
        return number;
    }

    public void Collect(int number) {
        if(!_dealtCards.Remove(number))
            throw new ArgumentException("Card is not in use", "number");

        _freeCards.Enqueue(number);
    }

    readonly HashSet<int> _dealtCards=new HashSet<int>();
    readonly Queue<int> _freeCards=new Queue<int>(); // "Pool" of free cards.
    int _lastNumber;
}
Run Code Online (Sandbox Code Playgroud)