https://www.cnblogs.com/soulmate/p/5607060.html
.net.Framework中提供了一个专门产生随机数的类System.Random,此类默认状况下已被导入,编程过程当中能够直接使用。html
咱们知道,计算机并不能产生彻底随机的数字,它生成的数字被称为伪随机数,它是以相同的几率从一组有限的数字中选取的,所选的数字并不具备彻底的随机性,但就实用而言,其随机程度已经足够了。算法
咱们能够用如下两种方法初始化一个随机数发生器;编程
函数是这样用,好比100至999的随机数
Random ran=new Random();
int RandKey=ran.Next(100,999);
不过这样会有重复,能够给Random一个系统时间作为参数,以此产生随机数,就不会重复了 数组
第一种方法
不指定随机种子,系统自动选取当前时前做随机种子:(Random ra = new Random(DateTime.Now.Millisecond);)
Random ra=new Random(); dom
第二种方法
是指定一个int型的参数做为随机种子:
int iSeed=6;
Random ra=new Random(iSeed);
下面咱们要用到Random.Next()方法产生随机数。
ra.Next();
它返回一个大于或等于零而小于2,147,483,647的数,这并不知足咱们的须要,下面咱们介绍它的重载函数和其它一些方法。
public virtual int Next(int);
用法:ra.next(20)
返回一个小于所指定最大值(此处为20)的正随机数。
public virtual int Next(int minValue, int maxValue);
用法:ra.next(1,20)
返回一个指定范围内(此处为1-20之间)的随机数,左闭右开,咱们在下面的实例中会用到此函数。
类System.Random还有几个方法分别是:
公共方法:
NextBytes用随机数填充指定字节数组的元素。
NextDouble返回一个介于 0.0 和 1.0 之间的随机数。
受保护的方法:
Sample返回一个介于 0.0 和 1.0 之间的随机数,只容许子类对象访问。
以上介绍了随机数的基本用法,下面咱们用一个实例来作更进一步的介绍。要在一段数字区间内随机生成若干个互不相同的随机数,好比在从1到20间随机生成6个互不相同的整数。
主要是下面两个函数getRandomNum与getNum:
public int[] getRandomNum(int num,int minValue,int maxValue)
{
Random ra=new Random(unchecked((int)DateTime.Now.Ticks));
int[] arrNum=new int[num];
int tmp=0;
for (int i=0;i<=num-1;i++){
tmp=ra.Next(minValue,maxValue); //随机取数
arrNum[i]=getNum(arrNum,tmp,minValue,maxValue,ra); //取出值赋到数组中
}
return arrNum;
}
getRandomNum便是在区间[minValue,maxValue]取出num个互不相同的随机数,返回的数组包含着结果。
其中随机数是这样建立的 Random ra=new Random(unchecked((int)DateTime.Now.Ticks));为何不用Random ra=new Random();(系统自动选取当前时前做随机种子)呢?
用系统时间作随机种子并不保险,若是应用程序在一个较快的计算机上运行,则该计算机的系统时钟可能没有时间在此构造函数的调用之间进行更改,Random 的不一样实例的种子值可能相同。这种状况下,咱们就须要另外的算法来保证产生的数字的随机性。因此为了保证产生的随机数足够"随机",咱们不得不使用复杂一点的方法来得到随机种子。在上面的这段程序中,咱们首先使用系统时间做为随机种子,而后将上一次产生的随机数跟循环变量和一个与系统时间有关的整型参数相乘,以之做为随机种子,从而获得了每次都不一样的随机种子,保证了产生足够"随机"的随机数。
函数getNum是一递归,用它来检测生成的随机数是否有重复,若是取出来的数字和已取得的数字有重复就从新随机获取。值得注意的是要用一同一个随机数实例生成,因此ra要做为参数传入getNum中,不然生成的数字会有重复。
public int getNum(int[] arrNum,int tmp,int minValue,int maxValue,Random ra){
int n=0;
while (n<=arrNum.Length-1)
{
if (arrNum[n]==tmp) //利用循环判断是否有重复
{
tmp=ra.Next(minValue,maxValue); //从新随机获取。
getNum(arrNum,tmp,minValue,maxValue,ra);//递归:若是取出来的数字和已取得的数字有重复就从新随机获取。
}
n++;
}
return tmp;
}
最后就是要显示出来,当点击一个button时取出的数字显示在一个label中。
private void button1_Click(object sender, System.EventArgs e)
{
int[] arr=getRandomNum(6,1,20); //从1至20中取出6个互不相同的随机数
int i=0;
string temp="";
while (i<=arr.Length-1){
temp+=arr[i].ToString()+"\n";
i++;
}
label1.Text=temp; //显示在label1中
}函数
开始是介绍一下random()函数和Math.random()函数,而后介绍一些由此引出的自定义函数.对于如何实战出一些效果,那须要想象的翅膀和其它AS基础的支持.而算法自己并不困难.最后我会介绍一个简单效果.但愿能启发读者的思惟.post
Random.Next() 返回非负随机数;url
Random.Next(Int) 返回一个小于所指定最大值的非负随机数spa
Random.Next(Int,Int) 返回一个指定范围内的随机数
一、random(number)函数介绍
见帮助文档,简单再提一下,random(number)返回一个0~number-1之间的随机整数.参数number表明
一个整数.
示例:
trace(random(5));
//复制到主场景第一帧.
二、Math.random()
见帮助文档。返回一个有14位精度的0~1之间的数,注意没有参数。据说MM是推荐用这个函数的,而不是上面那个.
示例:
trace(Math.random());
//复制到主场景第一帧.
三、自定义的函数
MM给咱们的就这两个函数了,可是需求与供给老是存在矛盾。咱们有时候须要的随机数可不是这么简单。
好比咱们想返回一个有两位小数的随机数,返回两个数之间的随机数,返回字母随机数,返回多个随机数等等,
这些都须要咱们本身编写函数来实现。下面的代码直接复制到主场景第一帧就能够调用了。注意有的函数须要入口参数。
# 返回一个共有n位数,其中m位是小数的随机数
function randomXiao(n,m){
var a = Math.pow(10, n+m);
var b = random(a);
return b=b/Math.pow(10, m);
}
能够用trace(randomXiao(3,2));实验一下。这个函数简单。Math.pow(n,m)用于返回一个以n为底,m为指数的数。乘方!
# 返回一个n到m之间的随机数
function randomNm(n,m){
if(m>=n){
return random(m-n+1)+n;
}
else {
return false;
}
}
之因此用random(m-n+1)是由于随机数的范围是m-n,加上1使得m也能在里面。加上n保证随机数以n为下限。
加上判断使函数更完整。另外,若是要返回一个负数随机数,也能够用randomNm(n,0);固然,我想更通常的是用-random(n);
# 返回一个字母
function randomAscii(){
var c = String.fromCharCode(random(26)+65);
if(random(2)){
return c.toLowerCase();
}
return c;
}
返回一个不区分大小写的随机字母
若是要返回大写,把if条件句去掉就好了。若是要返回小写,能够把条件句改成恒成立,或者去掉条件,最后一句改成:
return c.toLowerCase(); String.fromCharCode(number)函数返回number表明数字的ASCII码。
toLowerCase()用于将大写字母转为小写。
# 返回一个n到m之间的k个互异随机数
function randomKdiffer(n,m,k){
arrayK = [];
var i = 0;
while (i < k) {
a = random(m-n+1)+n;
for (var j = 0; j < i; j++) {
if (a == arrayK[j]) {
break;
}
}
if (j == i) {
arrayK[i] = a;
i++;
}
}
return arrayK;
}
数组arrayK中的元素即为所得值。注意到咱们借用了random(m-n+1)+n来返回一个n~m的随机数。因此m自己也会被返回。
若是要返回m之内的数,能够把n值改成0。若是要随机返回不肯定个数,能够把入口参数的K值赋为k=random(m-n);
随机返回不必定互异的数,把判断去掉就能够了,注意i++不要漏掉。这里再也不给出。
#指定若干个字符/数字,而后从中随机返回一个(或多个)字符/数字,能够把原字符赋给一个数组,再根据数组的下标来
决定返回值。这里再也不举出函数,你们能够本身尝试。
#另需指出,对于随机设定一个MC的颜色值,咱们较多采用mcColor.setRBG(random(0xFFFFFF));下面的例子中会有说明。
若是要指定一个色域,能够采用上面给出的函数。若是对Color对象不太了解的能够查帮助,这里不做讨论。
以上函数算是由random直接衍生的,下面再举个例子,能够说是衍生函数的衍生函数,其中会直接用到上面给出的函数,请注意。
#返回一个指定长度的随机大写英文字符串
function randomString(n){
var arrayA = randomKdiffer(1, 26, n);
var arrayB = "";
for (var i = 0; i < n; i++) {
c=String.fromCharCode(arrayA[i]+64);
/* if(random(2)){
c=c.toLowerCase();
}
*/
arrayB = arrayB+c;
}
return arrayB;
}
注意到StringCharCode方法,若是要写成小写,则把返回值写成arrayB.toLowerCase();若是返回一个不区分大小写的字符串,
则把注释去掉.若是要返回一个不指定长度的字符串,则能够把入口参数赋值为random(n);这样只指定其上限.此函数也能够用
randomAscii函数实现,留给你们本身思考.
#在几个区域中选出随机数
好比,在1~20,45~70这两段数之间选取一个随机数。由于区域数未定,因此直接用一个肯定的函数编写多有不便,
咱们要使用的方法就是用switch语句进行定向,具体的咱们给出一个函数,返回一个1~20,45~70内的数,其它区域读者请自行更改。
function randomArea(){
var a=random(2);
switch(a){
case 0:
return randomNm(1,20);break;
case 1:
return randomNm(45,70);break;
}
}
注意,咱们并无写入口参数,而是直接在函数中就肯定了是两段数,并且范围也是肯定的。若是是三段,则改成a=random(3);
一样增长一个case就能够了。固然,你也能够把第段数的范围设为入口参数,这里就再也不举例了。可是这样作可能会使参数增多,
我我的是不太喜欢一个须要不少参数的函数的。相似的,咱们也能够随机返回一个字母段或几个字母段或者字母加数字段的一个数。
方法也只是前几个函数的一个结合。这里仅举一例,返回指定的大写字母段的一个随机字母。
提醒一下,小写字母的ASCII码a~z分别对应97~122.
function randomAArea(a,b){
if (ord(a) <= ord(b) && 65<=ord(a) && ord(b) <= 90) {
return String.fromCharCode(randomNm(ord(a), ord(b)));
} else {
return false;
}
}
其中用到一个函数ord(char),这是一个不推荐的函数.用于返回char字符的ASCII码。
若是你们想在任何地方调用函数,则须要稍稍变一下,把咱们写的函数改变为全局函数.这样就能够不用标明路径而自如地向调用系统
函数同样了.方法以下.例如:函数randomXiao若是要声明为全局函数,须要把第一行改成:
_global.randomXiao=function(n,m){
//statment
}
对全局函数的概念不很清楚的朋友不用被这个名词吓倒.
这样改了函数第一行以后,在任何地方,好比在一个MC里,直接用(对,直接用,不用加_root路径了)randomXiao(n,m)就能够.net
Random类是一个产生伪随机数字的类,它的构造函数有两种,一个是直接New Random(),另一个是New Random(Int32),前者是根据触发那刻的系统时间作为种子,来产生一个随机数字,后者能够本身设定触发的种子,通常都是用UnCheck((Int)DateTime.Now.Ticks)作为参数种子,所以若是计算机运行速度很快,若是触发Randm函数间隔时间很短,就有可能形成产生同样的随机数,由于伪随机的数字,在Random的内部产生机制中仍是有必定规律的,并不是是真正意义上的彻底随机。
Random类产生随机数字的主要办法是Next(),Next(100)产生一个比100小的正整数,Next(1,100)在1到100中间产生一个随机数字,而利用Ticks(以100毫秒作基础单位的时间数量单位)来产生随机数,仍是存在合理性的。
1 /// <summary> 2 /// 用随机数实现一件事情出现的几率是10%,另外一件事情出现的几率是90% 3 /// </summary> 4 /// <param name="args"></param> 5 private static void Main(string[] args) 6 { 7 //string[] arr = { "10", "90", "90", "90", "90", "90", "90", "90", "90", "90" }; 8 Random ran = new Random(unchecked((int)DateTime.Now.Ticks)); 9 int num1 = 0; 10 int num2 = 0; 11 for (int i = 0; i < 100000; i++) 12 { 13 int n = ran.Next(0, 10); 14 //string str = arr[n]; 15 if (n == 0) 16 { 17 num1++; 18 } 19 else 20 { 21 num2++; 22 } 23 } 24 Console.Write(num1 + "--" + num2); 25 } 26 /// <summary> 27 ///举例:用等差几率取0-99的整数,但让99的出现概率最大,98比99小一点,97比98小一点,0出现的概率最小 28 /// </summary> 29 /// <param name="number"></param> 30 /// <returns></returns> 31 private static int GetRandom(int number) 32 { 33 int maxNumber = number + 1; 34 int maxRange = ((1 + maxNumber) * maxNumber) / 2; 35 Random rd = new Random(); 36 int randomNumber = Math.Abs(rd.Next() % maxRange); 37 int sum = 0; 38 for (int i = 0; i < maxNumber; i++) 39 { 40 sum += (maxNumber - i); 41 if (sum > randomNumber) 42 { 43 return i; 44 } 45 } 46 return -1; 47 }