如何生成一組不重復的隨機數


問題:生成隨機數的方法有很多,如利用 C# 中的 Random 類中 Next() 方法就可以生成。但是這樣生成的隨機數有可能會重復,如果需要生成不同的隨機數,有沒有相應的高效的方法呢?

分析:1.獲取生成隨機數的方法,這里用 Next 方法

        2.在生成隨機數之后立刻判斷它是否與之前生成的重復,如果重復則重新生成,否則繼續生成下一個

        3.優化循環語句

C#代碼:

using System;
using System.Threading;

namespace MyTest
{
    public class Program
    {
        static void Main(string[] args)
        {
            //隨機數的個數
            int count = 100;
            int[] data1 = new int[count];
            int[] data2 = new int[count];

            //調用不同的方法,產生隨機數
            Program pro = new Program();
            //產生隨機數的方法一
            data1 = pro.GetRandomData1(count);
            //輸出隨機數
            System.Console.Write("方法一產生了 {0} 個隨機數:\r\n", count);
            System.Console.Write(string.Join(" ", data1) + "\r\n");
            //產生隨機數的方法二
            data2 = pro.GetRandomData2(count);
            //輸出隨機數
            System.Console.Write("方法二產生了 {0} 個隨機數:\r\n", count);
            System.Console.Write(string.Join(" ", data2) + "\r\n");

            //產生隨機字符串
            System.Console.Write("產生了 10 個隨機字符串:\r\n");
            for (int i = 0; i < 10; i++)
            {
                System.Console.Write("{0}\r\n", pro.GetRandomStr(4));
                //產生一個隨機字符串后,線程停頓1毫秒,防止重復
                Thread.Sleep(1);
            }

            System.Console.ReadKey();
        }

        /// <summary>
        /// 功能:產生不同的隨機數,方法一
        /// 特點:和 GetRandomDatas2 方法相比,空間上節省了一個數組,但時間效率很低
        /// </summary>
        /// <param name="count">隨機數的個數</param>
        /// <returns>產生的所有隨機數</returns>
        public int[] GetRandomData1(int count)
        {
            int data = 0;
            int[] arr = new int[count];
            Random rand = new Random();

            //產生N個不同的隨機數
            for (int i = 0; i < count; i++)
            {
                data = rand.Next(0, count);
                //檢測當前隨機數是否在之前出現過
                for (int j = 0; j < i; j++)
                {
                    //如果之前出現過,則重新產生隨機數,並重新檢測
                    if (arr[j] == data)
                    {
                        data = rand.Next(0, count);
                        j = -1;
                    }
                }
                //如果之前未出現,則保存當前隨機數
                arr[i] = data;
            }
            return arr;
        }

        /// <summary>
        /// 功能:產生不同的隨機數,方法二
        /// 特點:和 GetRandomDatas1 方法相比,時間效率高很多,但多用了一個數組boo[],空間開銷較大
        /// 適用范圍:該方法只適用產生 “整數” 的隨機數的問題,不適用產生非整數隨機數:小數、負數等
        /// </summary>
        /// <param name="count">隨機數的個數</param>
        /// <returns>產生的所有隨機數</returns>
        public int[] GetRandomData2(int count)
        {
            int data = 0;
            int[] arr = new int[count];
            bool[] boo = new bool[count];
            Random rand = new Random();

            for (int i = 0; i < count; i++)
            {
                do
                {
                    // 如果產生的數相同繼續循環
                    data = rand.Next(count);
                }
                while (boo[data]);

                boo[data] = true;
                arr[i] = data;
            }
            return arr;
        }

        /// <summary>
        /// 附加功能:產生一個隨機純數字的字符串(如:驗證碼,也可以直接用 rand.Next(int minValue, int maxValue) 產生)
        /// 問題:如果產生兩個隨機字符串的時間間隔太短,有可能會出現重復的字符串
        /// </summary>
        /// <param name="strLength"></param>
        /// <returns></returns>
        private string GetRandomStr(int strLength)
        {
            string randomStr = "";
            int temp = -1;
            char[] allChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
            Random rand = new Random();

            for (int i = 0; i < strLength; i++)
            {
                if (temp != -1)
                {
                    rand = new Random(i * temp * ((int)DateTime.Now.Ticks));
                }
                int t = rand.Next(allChars.Length);
                if (temp == t)
                {
                    return GetRandomStr(strLength);
                }
                temp = t;
                randomStr += allChars[t];
            }
            return randomStr;
        }
    }
}

運行結果:

方法一產生了 100 個隨機數:

80 29 14 60 8 33 66 65 93 55 15 ...

方法而產生了 100 個隨機數:

80 29 14 60 8 33 66 65 93 55 15 ...

產生了 10 個隨機字符串:

8781

1957

1342

1528

1351

...


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM