洗牌算法分析(一)

来源:互联网 发布:powerdesigner 软件 编辑:程序博客网 时间:2024/05/02 02:28
 
这两天,在看《C# 入门经典》这本书,在第10章书的213页,有洗牌程序的一个例子。
 
洗牌的算法,简单介绍一下:
创建一个临时数组,把扑克牌从现有的cards数组随机复制到这个数组中。在复制每张牌的时候,把该数组中的指定为true。生成随机数时,检查这个数组,看这个位置的值是否为true.如果已经复制好了,就再生成另一个随机数。
 
整个代码如下:
////////////////////////////////////////////////////////////////
//                  Cards.cs 文件
//
////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Text;
 
namespace Ch10CardLib
{
    //扑克牌的花色
    public enum Suit
    {
        Club,
        Diamond,
        Heart,
        Spade
    }
    //扑克牌的顺序
    public enum Rank
    {
        Ace =1,
        Deuce,
        Three,
        Four,
        Five,
        Six,
        Seven,
        Eight,
        Nine,
        Ten,
        Jack,
        Queen,
        King
    }
    //牌类定义
    public class Card
    {
        public readonly Suit suit;
        public readonly Rank rank;
       
       //重写ToString函数
        public override string ToString()
        {
            return "The " + rank + " of " + suit;
        }
       
        //默认的构造函数
        private Card()
        {
        }
 
       //非默认构造函数
        public Card(Suit newSuit, Rank newRank)
        {
            suit = newSuit;
            rank = newRank;
        }
    }
}
 
 
////////////////////////////////////////////////////////////////////
//                          Deck。cs文件
//
///////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Text;
 
namespace Ch10CardLib
{
    public class Deck
    {
        private Card[] cards;

        //每次迭带创建一副牌
        public Deck()
        {
            cards = new Card[52];
            for (int suitVal = 0; suitVal < 4; suitVal++)
            {
                for (int rankVal = 1; rankVal < 14; rankVal++)
                {
                    cards[suitVal * 13 + rankVal - 1] = new Card((Suit)suitVal, (Rank)rankVal);
                }
            }
        }
 
        //
        public Card GetCard(int cardNum)
        {
            if (cardNum >= 0 && cardNum <= 51)
            {
                return cards[cardNum];
            }
            else
            {
                throw(new System.ArgumentOutOfRangeException("cardNum",cardNum,
                    "Value must be between 0 and 51."));
            }
        }
 
        //洗牌
        public void Shuffle()
        {
            //创建一个临时的扑克牌组
            Card[] newDeck = new Card[52];
            //bool变量数组
            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)
                {
                    //生成一个0到51之间的随机数
                    destCard = sourceGen.Next(52);
                    if (assigned[destCard] == false)
                    {
                        foundCard = true;
                    }
                }
                assigned[destCard] = true;
                newDeck[destCard] = cards[i];
            }
            newDeck.CopyTo(cards, 0);   //留心这个使用的方法
        }
    }
}
 
 
//////////////////////////////////////////////////////////////////////////
//                     Console application
//
//////////////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Text;
using Ch10CardLib;
 
namespace Ch10CardClient
{
    class Class1
    {
        static void Main(string[] args)
        {
            Deck myDeck = new Deck();
            myDeck.Shuffle();
            for (int i = 0; i < 52; i++)
            {
                Card tempCard = myDeck.GetCard(i);
                Console.WriteLine(tempCard.ToString());
                if (i != 51)
                {
                    Console.Write(",");
                }
                else
                {
                    Console.WriteLine();
                }
            }
        }
    }
}
 
其中,重点就是洗牌的算法了。但这段洗牌的程序算法效率不好。
原创粉丝点击