產生一個int數組,長度為100,並向其中隨機插入1-100,並且不能重復


寫在前面

前天去面試了,給出的筆試中有這樣的一道算法題,產生一個int數組,長度為100,並向其中隨機插入1-100,並且不能重復

當時,腦子一熱,也沒想那么多,就用集合實現了一下,經面試官提醒,發現還有更好的方式來實現。

代碼

首先看一下這樣一段代碼

 1 namespace Wolfy.RandomDemo
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             List<int> lst = new List<int>();
 8             Random r = new Random();
 9             while (true)
10             {
11                 int temp = r.Next(1, 101);
12                 if (lst.Count == 100)
13                 {
14                     break;
15                 }
16                 if (!lst.Contains(temp))
17                 {
18                     lst.Add(temp);
19                 }
20             }
21             for (int i = 0; i < lst.Count; i++)
22             {
23                 Console.WriteLine(lst[i]);
24             }
25             Console.Read();
26         }
27     }
28 }

 雖然上面的代碼,實現題目的要求,但是如果是1到100萬或者更大,這樣的每次判斷是否包含這樣的一個數,勢必會影響到性能。

網上找到一種更好的實現方式:

(1)把N個數放到容器A(int數組)中.

(2)從N個數中隨機取出1個數放入容器B(int數組)中.

(3)把容器A中最后一個數與隨機抽取的數對調 或者 把容器A中最后一個數覆蓋隨機抽取出來的數.

(4)這時從容器A(假設N個數,索引0 到 索引N-2)之間隨機取一個數.再放入容器B中,重復此步驟.

說明:也就是第二次是從容器A中 第一個元素到倒數第二個元素 中隨機取一個數.

這種好處是,隨機數所取范圍逐步縮小,而且杜絕了大數據時集合執行刪除操作時產生的瓶頸.

代碼實現

 1 namespace Wolfy.RandomDemo
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             int[] result = GetRandom(100);
 8             for (int i = 0; i < result.Length; i++)
 9             {
10                 Console.WriteLine(result[i]);
11             }
12             Console.WriteLine("over:" + result.Length);
13             Console.Read();
14         }
15         /// <summary>
16         /// 獲得無重復隨機數組
17         /// </summary>
18         /// <param name="n">上限n</param>
19         /// <returns>返回隨機數組</returns>
20         static int[] GetRandom(int n)
21         {
22             //容器A和B
23             int[] arryA = new int[n];
24             int[] arryB = new int[n];
25             //填充容器a
26             for (int i = 0; i < arryA.Length; i++)
27             {
28                 arryA[i] = i + 1;
29             }
30             //隨機對象
31             Random r = new Random();
32             //最后一個元素的索引 如n=100,end=99
33             int end = n - 1;
34             for (int i = 0; i < n; i++)
35             {
36                 //生成隨機數 因為隨機的是索引 所以從0到100取,end=100
37                 //一個大於等於 minValue 且小於 maxValue 的 32 位帶符號整數,即:返回的值范圍包括 minValue 但不包括 maxValue。 
38                 //如果 minValue 等於 maxValue,則返回 minValue
39                 //
40                 int minValue = 0;
41                 int maxValue = end + 1;
42                 int ranIndex = r.Next(minValue, maxValue);
43                 //把隨機數放在容器B中
44                 arryB[i] = arryA[ranIndex];
45                 //用最后一個元素覆蓋取出的元素
46                 arryA[ranIndex] = arryA[end];
47                 //縮減隨機數生成的范圍
48                 end--;
49             }
50             //返回生成的隨機數組
51             return arryB;
52         }
53     }
54 }

總結

實現方式有很多種,但是如果能用高效的方式就用高效的方式實現。這種生成無重復的隨機數,可以在運用在抽獎系統中。


免責聲明!

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



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