1. 程式人生 > >如何產生1-100 之間的100個不重複的隨機數

如何產生1-100 之間的100個不重複的隨機數

1:首先從原始陣列中隨機選擇一個數字,然後將該數字從陣列中剔除,再隨記選,再剔除,重複99次,就解決了。

    我們知道從陣列中剔除一個元素的複雜度為O(N),那麼隨機選取n個數字,它的複雜度就是O(N2)了。

2:用hash作為中間過濾層,因為在陣列中,我們採用隨機數的話,也許隨機數在多次隨機中可能會有重複,所以需要用hash來判斷一下,

    如果在hash中重複,則繼續產生隨機數,直到不重複為止,當然這個複雜度就不好說了,得要看隨機數隨機不隨機了,好的話,O(N)搞定,

    不走運的話無上限~

3:就像標題說的一樣,很多問題我們都能在現實生活中找到寫照,畢竟很多東西是來源於現實,又抽象於現實,比如這個題目在現實生活中,

  可以對應到的就是“洗撲克牌”,在演算法中也叫“洗牌原理”,我們知道洗撲克牌的方式就是隨機的交換撲克牌的位置,又叫做"切牌",當你切了

   很多次後,我們的撲克牌就可以認為是足夠亂了,複雜度也就變成了O(N),用程式碼實現就是這樣的。

   <1> 先有序的生成52張牌,然後有序的放到陣列中。

   <2>從1-52中隨機的產生一個數,然後將當前次數的位置跟隨機數的位置進行交換,重複52次,我們的牌就可以認為足夠亂了。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    public class Program
    {
        static void Main(string[] args)
        {
            CardClass cc = new CardClass();

            cc.NewCard();

            Console.WriteLine("\n\n=======================洗牌之前  ===========================\n");
            cc.Output();

            Console.WriteLine("\n\n=======================洗牌之後  ===========================\n");
            cc.Shuffle();
            cc.Output();


            Console.Read();
        }
    }

    public class CardClass
    {
        public Card[] card = new Card[52];

        /// <summary>
        /// 具體撲克牌
        /// </summary>
        public class Card
        {
            public char suit;

            public string num;
        }

        /// <summary>
        /// 開牌
        /// </summary>
        public void NewCard()
        {
            for (int i = 1; i <= card.Length; i++)
            {
                var suit = ((i - 1) / 13) + 3;
                var num = i % 13;

                string temp;

                switch (num)
                {
                    case 1: temp = "A"; break;
                    case 11: temp = "J"; break;
                    case 12: temp = "Q"; break;
                    case 0: temp = "K"; break;
                    default: temp = num.ToString(); break;
                }

                card[i - 1] = new Card()
                {
                    suit = (char)suit,
                    num = temp
                };
            }
        }

        /// <summary>
        /// 洗牌
        /// </summary>
        public void Shuffle()
        {
            for (int i = 0; i < card.Length; i++)
            {
                var rand = new Random((int)DateTime.Now.Ticks).Next(0, card.Length);

                //因為隨機數是偽隨記,正真的隨機數是要跟硬體打交道的,所以這裡設定了停留1ms
                System.Threading.Thread.Sleep(1);

                var temp = card[rand];

                card[rand] = card[i];

                card[i] = temp;
            }
        }

        /// <summary>
        /// 輸入牌型
        /// </summary>
        public void Output()
        {
            for (int i = 0; i < card.Length; i++)
            {
                if (i % 13 == 0)
                    Console.WriteLine();

                Console.Write("{0}{1} ", card[i].suit, card[i].num);
            }
        }
    }
}