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

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

 

     若是這是你是第一次看到這個題目,也許你的想法有不少。數組

 

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

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

 

2:用hash做爲中間過濾層,由於在數組中,咱們採用隨機數的話,也許隨機數在屢次隨機中可能會有重複,因此須要用hash來判斷一下,ide

    若是在hash中重複,則繼續產生隨機數,直到不重複爲止,固然這個複雜度就很差說了,得要看隨機數隨機不隨機了,好的話,O(N)搞定,ui

    不走運的話無上限~this

 

3:就像標題說的同樣,不少問題咱們都能在現實生活中找到寫照,畢竟不少東西是來源於現實,又抽象於現實,好比這個題目在現實生活中,spa

  能夠對應到的就是「洗撲克牌」,在算法中也叫「洗牌原理」,咱們知道洗撲克牌的方式就是隨機的交換撲克牌的位置,又叫作"切牌",當你切了code

   不少次後,咱們的撲克牌就能夠認爲是足夠亂了,複雜度也就變成了O(N),用代碼實現就是這樣的。blog

   <1> 先有序的生成52張牌,而後有序的放到數組中。

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

 

4:代碼實現

<1> 首先定義牌的數據結構,定義一個「花色」和「數字」

複製代碼
1         /// <summary> 2 /// 具體撲克牌 3 /// </summary> 4 public class Card 5  { 6 public char suit; 7 8 public string num; 9 }
複製代碼

 

<2>有序的生成52張牌

複製代碼
 1         /// <summary>  2 /// 開牌  3 /// </summary>  4 public void NewCard()  5  {  6 for (int i = 1; i <= card.Length; i++)  7  {  8 var suit = ((i - 1) / 13) + 3;  9 var num = i % 13; 10 11 string temp; 12 13 switch (num) 14  { 15 case 1: temp = "A"; break; 16 case 11: temp = "J"; break; 17 case 12: temp = "Q"; break; 18 case 0: temp = "K"; break; 19 default: temp = num.ToString(); break; 20  } 21 22 card[i - 1] = new Card() 23  { 24 suit = (char)suit, 25 num = temp 26  }; 27  } 28 }
複製代碼

 

<3> 而後就是切牌了,剛纔也說了思路,就是拿隨機數的位置與當前i的位置進行交換,不過一說到交換就想起了「冒泡排序」,可能被毒害太

  深了(┬_┬),不知道你感受到了沒。

複製代碼
 1         /// <summary>  2 /// 洗牌  3 /// </summary>  4 public void Shuffle()  5  {  6 for (int i = 0; i < card.Length; i++)  7  {  8 var rand = new Random((int)DateTime.Now.Ticks).Next(0, card.Length);  9 10 //由於隨機數是僞隨記,正真的隨機數是要跟硬件打交道的,因此這裏設置了停留1ms 11 System.Threading.Thread.Sleep(1); 12 13 var temp = card[rand]; 14 15 card[rand] = card[i]; 16 17 card[i] = temp; 18  } 19 }
複製代碼

<4> 最後咱們看看效果

  1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Text;  5 using System.Threading.Tasks;  6  7 namespace ConsoleApplication1  8 {  9 public class Program  10  {  11 static void Main(string[] args)  12  {  13 CardClass cc = new CardClass();  14  15  cc.NewCard();  16  17 Console.WriteLine("\n\n=======================洗牌以前 ===========================\n");  18  cc.Output();  19  20 Console.WriteLine("\n\n=======================洗牌以後 ===========================\n");  21  cc.Shuffle();  22  cc.Output();  23  24  25  Console.Read();  26  }  27  }  28  29 public class CardClass  30  {  31 public Card[] card = new Card[52];  32  33 /// <summary>  34 /// 具體撲克牌  35 /// </summary>  36 public class Card  37  {  38 public char suit;  39  40 public string num;  41  }  42  43 /// <summary>  44 /// 開牌  45 /// </summary>  46 public void NewCard()  47  {  48 for (int i = 1; i <= card.Length; i++)  49  {  50 var suit = ((i - 1) / 13) + 3;  51 var num = i % 13;  52  53 string temp;  54  55 switch (num)  56  {  57 case 1: temp = "A"; break;  58 case 11: temp = "J"; break;  59 case 12: temp = "Q"; break;  60 case 0: temp = "K"; break;  61 default: temp = num.ToString(); break;  62  }  63  64 card[i - 1] = new Card()  65  {  66 suit = (char)suit,  67 num = temp  68  };  69  }  70  }  71  72 /// <summary>  73 /// 洗牌  74 /// </summary>  75 public void Shuffle()  76  {  77 for (int i = 0; i < card.Length; i++)  78  {  79 var rand = new Random((int)DateTime.Now.Ticks).Next(0, card.Length);  80  81 //由於隨機數是僞隨記,正真的隨機數是要跟硬件打交道的,因此這裏設置了停留1ms  82 System.Threading.Thread.Sleep(1);  83  84 var temp = card[rand];  85  86 card[rand] = card[i];  87  88 card[i] = temp;  89  }  90  }  91  92 /// <summary>  93 /// 輸入牌型  94 /// </summary>  95 public void Output()  96  {  97 for (int i = 0; i < card.Length; i++)  98  {  99 if (i % 13 == 0) 100  Console.WriteLine(); 101 102 Console.Write("{0}{1} ", card[i].suit, card[i].num); 103  } 104  } 105  } 106 }
View Code

 

其實「洗牌原理」只要說破了是很簡單的,就是你想不到,哈哈。。。而後小師弟也就明白了,我也就繼續看徐錦江的精彩表現了,o(∩_∩)o 

相關文章
相關標籤/搜索