如何产生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> 首先定义牌的数据结构,定义一个“花色”和“数字”
View Code
其实“洗牌原理”只要说破了是很简单的,就是你想不到,哈哈。。。然后小师弟也就明白了,我也就继续看徐锦江的精彩表现了,o(∩_∩)o
如果这是你是第一次看到这个题目,也许你的想法有很多。
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
相关文章推荐
- 如何产生1-100 之间的100个不重复的随机数
- 产生100个100以内不重复随机数的代码
- [引]用c#产生1-100之间的不重复的随机数,并且可进行降序 升序排序
- 如何生成100个1-100以内的不重复的随机数
- 产生一个长度为100的数组,为数组中的每一项随机填充1-100之间的数并且保证不重复
- 如何高效产生m个n范围内的不重复随机数(m<=n)
- 使用Random产生100个无重复随机数,使用Set存储和使用位图存储的效率对比
- C++产生m到n之间的随机数,产生0到100之间的随机数,以系统时间作为随机种子
- 如何产生不重复的随机数?最容易想到的方法,是逐个产生这些随机数,每产生一个,都跟前面的随机数比较,如果重复,就重新产生。这是个很笨的方法,且比较次数呈线性增长,越往后次数越多。其实这些比较是多余的,
- 给定一个函数rand()能产生0到n-1之间的等概率随机数,问如何产生0到m-1之间等概率的随机数?
- flash中随机产生20-100之间10个不同的数字,然后不能重复地随机取出这十个数字
- 面试题:产生一个长度为100的数组,为数组中的每一项随机填充1-100之间的数并且保证不重复
- 面试题:产生一个长度为100的数组,为数组中的每一项随机填充1-100之间的数并且保证不重复
- 给定一个函数rand()能产生0到n-1之间的等概率随机数,问如何产生0到m-1之间等概率的随机数?
- C++如何产生100个随机数
- 生成100个100~50之间的随机数 一行一个数
- 如何高效产生m个n范围内的不重复随机数(m<=n)
- 如何高效产生m个n范围内的不重复随机数(m<=n)
- 产生一个int数组,随机向数组中插入1-100的随机数且不能重复
- 产生一个int数组,随机向数组中插入1-100的随机数且不能重复