日期:2014-05-18  浏览次数:20965 次

一个洗牌方法 麻烦高手来看看我这问题。。。
照着例子 弄了个洗牌的方法
C# code
public void shuffle()
        {
            Card[] newDeck = new Card[52];
            bool[] assigned = new bool[52];
            Random sourceGen = new Random();
            for (int i = 0; i < 52; i++)
            {
                int destCard = 0;
                bool foundCard = false;
                while (foundCard == false)
                {
                    destCard = sourceGen.Next(52);
                    if (assigned[destCard] == false)
                       foundCard = true;
                }
                assigned[destCard] = true;
                newDeck[destCard] = cards[i];
            }
            newDeck.CopyTo(cards, 0);

        }


  【上边是代码】
Cards是另外一个card数组  
【请问】destCard = sourceGen.Next(52);这个会生成重复的数吗?如果会的话上边这段代码不就有可能产生覆盖了吗 ?
比如第一次是3,而第二次还是3那第二次的数据不就把第一次给覆盖了 而它一共才循环52次 这怎么能保证数组随机地打乱呢? 我运行了程序 确实是可以 可是代码就是看不明白。。。希望谁来帮帮忙。。。

------解决方案--------------------
这样:
C# code
List<int> oldcard = new List<int>()
{1,2,3,4,5,6....};
List<int> newcard = new List<int>();
Random r = new Random();
while (oldcard.Count > 0)
{
    n = r.Next(0,oldcard.Count);
    newcard.Add(oldcard[n]);
    oldcard.RemoveAt(n);
}

------解决方案--------------------
探讨

这样:
C# code
List<int> oldcard = new List<int>()
{1,2,3,4,5,6....};
List<int> newcard = new List<int>();
Random r = new Random();
while (oldcard.Count > 0)
{
n = r.Next(0,oldcard.Count);
new……

------解决方案--------------------
不会重复,因为while (foundCard == false)保证了这一点
你要是实在看不懂代码,应该加断点调试一下,看看代码的执行流程
------解决方案--------------------
destCard = sourceGen.Next(52)会生成重复的数字, 
while中操作确保了生成的数字不会重复,明显的问题就是这里的while损耗是不定的,而且随着i的增长会越来越明显

------解决方案--------------------
洗牌要那么复杂么?

C# code
int[] result = Enumerable.Range(1, 52)
    .Select(x => new { r = Guid.NewGuid().ToString(), v = x })
    .ToList()
    .OrderBy(x => x.r)
    .Select(x => x.v)
    .ToArray();