您的位置:首页 > 其它

如何产生1-100之间的100个不重复的随机数

2014-08-30 21:55 411 查看
如何产生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次,我们的牌就可以认为足够乱了。

4:代码实现

<1> 首先定义牌的数据结构,定义一个“花色”和“数字”

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐