C#学习教程:如何在不存储卡片的情况下实施经销商类别?分享


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


有关更多信息,请按以下方式

  • 示例代码

     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算法。 典型的混洗算法是Fisher-Yates 。 shuffle算法将创建一个以随机顺序列出卡号的数组(13,5,7,18,22,…等)。 处理你从数组中的第一个元素开始并继续前进。

    我也在努力查看整个图片,但你可以将每个排列转换为base(52),其中一个字符代表每张卡片,并且有一个代表每个排列的字符串。

    所以黑桃可能是1-9 (ace - 9)0ABC (10, JQK) ,然后是DEFG ……开始心灵等等。

    所以一张3张牌,2张Spade(2),3张Heart(F)和2张Diamond(比如说e),会有这些排列数字:

     2Fe 2eF F2e Fe2 eF2 e2F 

    您可以通过将基数52转换为基数为10的转换来来回转换为int / long / bigint。

    这是对基数之间转换的介绍 。

    所以e2F将是F + 2*52 + e * 52^2 ,这将是16 + 2*52 + 43*52*52 = 116392

    所以116392将是你的排列数。

    (顺便说一下。我猜它是2颗钻石是’e’和43,你可以数一数,看看它究竟是什么样的)

    解决此问题的一种方法是使用(伪)随机数生成器(如Mersenne Twister ),然后仅存储每笔交易的种子编号。 由于每次从同一种子获得相同的随机数序列,它用于表示整个交易(使用从该种子生成的随机数来驱动所发出的卡)。

    [编辑…]

    该交易的一些伪代码:

     while (#cards < cardsNeed) card = getCard(random()) if (alreadyHaveThisCard(card)) continue [do something with the card...] 

    如果我理解正确,以下代码实现了这一点:

     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 _dealtCards=new HashSet(); readonly Queue _freeCards=new Queue(); // "Pool" of free cards. int _lastNumber; } 

    虽然我在理解你在这里想要实现的内容时遇到了一些问题,但我认为互质会产生一堆排列数; 那就是:如果你不太关心分配。 你可以使用Euclidian算法 。

    代数(集合论)表明你可以简单地使用x =(x + coprime)%set.Length来获取集合中的所有元素。 我想每个互质都是你描述的排列数。

    那就是说我不确定使用生成的互质作为“随机数发生器”时你得到的分布是什么; 我想某些分布将比其他分布更频繁地发生,并且许多分布将从生成的数字中排除,原因很简单,因为生成器将在环中选择数字。 我在这里有点创意,所以也许它符合你的需求,虽然它可能不是你想要的答案。

    我真的不明白你的问题,但我这样解释:你想要计算一系列52张牌的permutationIndex 。 给定的排列索引一对一地映射到一系列卡片。 既然有52个! 52张卡的可能安排,你需要至少226位,或29字节。 那么,你的permutationIndex已经非常大了!

    由于您的排列索引已经是29个字节长,因此一些额外的字节不会产生很大的差异并使解决方案变得更容易。


    例如,您可以将拉丁字母的每个字母映射到卡片。 鉴于我们有26个小写字母,26个大写字母,我们有52个字母可以代表52张卡片。

        abcdefghijklm nopqrstuvwxyz  ♥A234567890JQK♦A234567890JQK     ABCDEFGHIJKLM NOPQRSTUVWXYZ  ♣A234567890JQK♠A234567890JQK 

    现在你可以创建一个包含52个字母的字符串。 每个唯一的字母串代表52张卡的独特排列。 有了这个你可以:


    字符串中的每个字符都表示为(在C#中)为16位Unicode值,但对于52个卡,您只需要6位。 所以你有更多的选择来选择一个表示:

    1. 832位,或10​​4字节:52个Unicode字符的字符串
    2. 416位,或52字节:52字节的数组
    3. 320位或40字节:10个32位整数的数组,用于保存52 * 6位
    4. 312位或39字节:39字节的数组,用于保存52 * 6位
    5. 226位,或29个字节:绝对下限

    表示3和4需要相当一些聪明的比特摆弄以获得特定卡的6位不在序列中。 我会推荐代表2,它保留了上面提到的大部分优点。


    当您使用二进制表示而不是字符串表示时,您可以为每张卡创建一个具有唯一值的枚举,并使用:

     public enum Cards : byte { HeartsAce HeartsTwo // ... HeartsTen HeartsJack HeartsQueen HeartsKing DiamondsAce DiamondsTwo // ... SpadesTen SpadesJack SpadesQueen SpadesKing } 

    你有一个非常有效的c#例子,在这个非常古老的post中, 对于n阶的第k个排列 (又名PermutationIndex):

    对于那些对组合主题感兴趣的人:


    在进入具体实施之前,我建议你仔细阅读。

    和其他人一样,我不确定你想要做什么,但是如果你想在通信卡的通信/存储上节省尽可能多的空间,我会做以下事情:

    我会使用带有flag属性的枚举来存储在单个Long上处理的卡片,因此我可以使用按位比较来查看已经处理了哪个卡片。

    因为每张卡片都是一个单独的“旗帜”,其唯一编号设置为2的指数,所以它们永远不会发生冲突。

    总的来说,即使您处理所有卡,存储仍将是8个字节。 你需要的任何额外数据,你可以在最后。

    请参阅下面的工作示例。

    上述就是C#学习教程:如何在不存储卡片的情况下实施经销商类别?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注---猴子技术宅(www.ssfiction.com)

     using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication12 { class Program { static void Main(string[] args) { // Because each card is unique you could use Flag attributed Enum see the enum below and set each item a unique value I used 2 to the power of 52 Cards cardsdealt = Cards.Clubs_10 | Cards.Clubs_2 | Cards.Diamonds_3; if ((cardsdealt & Cards.Clubs_10) == Cards.Clubs_10) { Console.WriteLine("Card.Clubs_10 was dealt"); } // Storage would always be 8 bytes for the long data type } [Flags] public enum Cards : long { Spades_Ace = 1, Spades_2 = 2, Spades_3 = 4, Spades_4 = 8, Spades_5 = 16, Spades_6 = 32, Spades_7 = 64, Spades_8 = 128, Spades_9 = 256, Spades_10 = 512, Spades_Jack = 1024, Spades_Queen = 2048, Spades_King = 4096, Hearts_Ace = 8192, Hearts_2 = 16384, Hearts_3 = 32768, Hearts_4 = 65536, Hearts_5 = 131072, Hearts_6 = 262144, Hearts_7 = 524288, Hearts_8 = 1048576, Hearts_9 = 2097152, Hearts_10 = 4194304, Hearts_Jack = 8388608, Hearts_Queen = 16777216, Hearts_King = 33554432, Diamonds_Ace = 67108864, Diamonds_2 = 134217728, Diamonds_3 = 268435456, Diamonds_4 = 536870912, Diamonds_5 = 1073741824, Diamonds_6 = 2147483648, Diamonds_7 = 4294967296, Diamonds_8 = 8589934592, Diamonds_9 = 17179869184, Diamonds_10 = 34359738368, Diamonds_Jack = 68719476736, Diamonds_Queen = 137438953472, Diamonds_King = 274877906944, Clubs_Ace = 549755813888, Clubs_2 = 1099511627776, Clubs_3 = 2199023255552, Clubs_4 = 4398046511104, Clubs_5 = 8796093022208, Clubs_6 = 17592186044416, Clubs_7 = 35184372088832, Clubs_8 = 70368744177664, Clubs_9 = 140737488355328, Clubs_10 = 281474976710656, Clubs_Jack = 562949953421312, Clubs_Queen = 1125899906842620, Clubs_King = 2251799813685250, } } } 

    本文来自网络收集,不代表猴子技术宅立场,如涉及侵权请点击右边联系管理员删除。

    如若转载,请注明出处:https://www.ssfiction.com/ckf/959800.html

    发表评论

    邮箱地址不会被公开。 必填项已用*标注