好玩的取随机数

时间:2022-11-28 04:40:45
在一个数组中,有很多整数,
现在我想取其中的随机数,
但我想让数值大的数的机率高
如:(1,1,4,6,4,7,7,3,3,7)
我想让1的机会是一次
而4的机会是4次
7的机会是7次
怎么办呢?

25 个解决方案

#1


解出
n*(n-1)/2<=random<=n*(n+1)/2
的n

#2


#include<time.h>
#include<stdio.h>
#include<stdlib.h>

main()
{
  int i;

  randomize();
  i=random(20);
  switch(i)
    {
       case 0:
  printf("1");
  break;
       case 1:
       case 2:
       case 3:
 printf("3");
 break;
        ……
      case 14:
      case 15:
      case 16:
      case 17:
      case 18:
      case 19:
      case 20:
           printf("7");
        break;
    
    }
}



#3


建立一个数组p[],初始化全部为0,随机取数,

比如:随机取数

第一次取2  p[2]=p[2]+1      p[2]=1    取出
第二次取1  p[1]=p[1]+1      p[1]=1    取出 
第三次取1  p[1]=p[1]+1   因为p[1]>1  不要,继续
第四次取2  p[2]=p[2]+1      p[2]=2    取出
第五次取3  p[3]=p[3]+1      p[3]=1    取出
第六次取2  p[2]=p[2]+1   因为p[2]>2  不要,继续
……

就这样,简单吧!

呵呵!

#4


to:kj_stone(stone)

你写的是什么东西呀?

#5


(1,1,4,6,4,7,7,3,3,7)
这个数组你不能自己建一个吗?

你把它建成:
{1,2,2,3,3,3,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,7}

在里面取数,就可以了呀!

#6


: kj_stone(stone) 写了一个多么简单优雅的解决方案!!

#7


easy

#8


to sclzmbie(梦里红尘)

我不理解他的程序,你能给我分析一下吗?

谢谢!

#9


我的想法和one_add_one()快给分给分()一样

#10


 one_add_one和kj_stone的方法都行,只不过one_add_one的方法比较新奇

#11


刚才又看了一遍kj_stone的方法,终于理解了!

哈哈!

#12



哈哈题目给出的数组的总概率超过了一!是无解的!哈哈!
白折腾了!你们!呵呵~~~

#13



感谢大吓们的热情!!!!
先说一下 kj_stone(stone) 的解:
这个解可以把大数的概率取多次,可是有一个问题
不能算出究竟是哪个数,比如在数组a()中,
a(2)和a(8)都是4哪么我算出的这个case究竟是哪个4 呢
是a(2)还是a(8)呢?

one_add_one()快给分给分() 
的方法真有些意思

#14


这个问题大概可以称为权随机问题,准形式化的表达可以是这样:
在n的元素的空间(N1,N2,...,Nn)中,Ni元素的出现次数为Ri(必须为每个元素定义),
普通的随机即为R1 = R2 = ... = Rn 的特殊情况。

算法可以是这样:
定义一个新的样本空间,使元素个数为R1 + R2 + ... + Rn.记为M。使得
M[0] = M[1] = ... M[R1-1] = 1
M[R1] = ... = M[R2-1] = 2
...
M[Ri] = ... = M[R(i+1) - 1 ] = i
...
M[Rn-1] = ...= M[Rn] = n
在这个数组中利用rand()取随机树,k = rand() . 则N[M[Rk]即为结果。
这就是one_add_one()快给分给分()的算法吧。也是我现在想到的唯一的算法.当然优化的办法还有.

#15


用这个公式:

x=[(sqrt(1+8*rnd)-1)/2]+1

简单吧!


我刚刚推出来的,呵呵!

#16


上面的式子中rnd是是你的计算机生成的随机数,rnd<n(n+1)/2。

#17


#inckude(stdio.h)
main()
       {int p[7];
       int i;
START: for(i=1;i<=7;i++)/*给数组赋值 数组从p[1]到p[7] 分别赋以初值1 2 3 4 5 6 7 */
       p[i]=i;
       printf("please input the data/n");
       scanf("%d",&k);
       if(k<0 or k>7)
       printf("error input/n")
       else i=k;
       if(p[i]!=0)printf("%d",i)/*若数组为0,则不输出*/
       p[i]=p[i]-1;/*每输出一个数,使相应的数组减一*/
       while(p[1]=0&&p[2]=0&&p[3]=0&&p[4]=0&&p[5]=0&&p[6]=0&&p[7]=0)goto START
    }是不是很简单??

#18


 大家觉得我的程序是不是能实现上述功能 

#19


编译通不过!

我觉得算法不灵活!

#20


大家好涌跃啊!!!! 感谢感谢


to:wwl_f117(孤独之狼) 
您的程序只有在多次抽取后才有意义,
但我想只抽一次的话就不好使了.

to:one_add_one()快给分给分()
你的公式有一点小问题,当这个数组中的数只出现一次时好用.
但当这个数组中有重复数的时候就有问题了.

现在我把这道题给大家扩展一下:
有一个数据库有两个字段,DATA 和 COUNT

DATA COUNT
A 5
B 8
C 1
D 8
E 6
这个数据库的记录个数是不定的
ID号的生成也是随机的
现在我需要从DATA 随机中取出一个数据
当然这个随机要根据 count 的值来确定出现概率
的大小.

就好象是一个购物抽奖程序, 
DATA 是你的名字, COUNT 是你购物的个数
当然你购物的个数越多,抽奖的机率就越大了.

#21


那就建一个这样的就行了:

{C,A,A,A,A,A,E,E,E,E,E,E,D,D,D,D,D,D,D,D,B,B,B,B,B,B,B,B}

然后再取不就行了?

#22


to:one_add_one()快给分给分()
这是最基本的算法,没什么意思.
我想要有意思一点的算法.

#23


你只是问怎么办,没问有没有意思呀!


那我再想想!

#24


上面的算法有很大的优化余地,一定能满足需要!

你现在是要解决问题,还是要干什么?

#25


当然我的分还是要给的,只不过大家再继续研究出更优秀的作法吗

#1


解出
n*(n-1)/2<=random<=n*(n+1)/2
的n

#2


#include<time.h>
#include<stdio.h>
#include<stdlib.h>

main()
{
  int i;

  randomize();
  i=random(20);
  switch(i)
    {
       case 0:
  printf("1");
  break;
       case 1:
       case 2:
       case 3:
 printf("3");
 break;
        ……
      case 14:
      case 15:
      case 16:
      case 17:
      case 18:
      case 19:
      case 20:
           printf("7");
        break;
    
    }
}



#3


建立一个数组p[],初始化全部为0,随机取数,

比如:随机取数

第一次取2  p[2]=p[2]+1      p[2]=1    取出
第二次取1  p[1]=p[1]+1      p[1]=1    取出 
第三次取1  p[1]=p[1]+1   因为p[1]>1  不要,继续
第四次取2  p[2]=p[2]+1      p[2]=2    取出
第五次取3  p[3]=p[3]+1      p[3]=1    取出
第六次取2  p[2]=p[2]+1   因为p[2]>2  不要,继续
……

就这样,简单吧!

呵呵!

#4


to:kj_stone(stone)

你写的是什么东西呀?

#5


(1,1,4,6,4,7,7,3,3,7)
这个数组你不能自己建一个吗?

你把它建成:
{1,2,2,3,3,3,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,7}

在里面取数,就可以了呀!

#6


: kj_stone(stone) 写了一个多么简单优雅的解决方案!!

#7


easy

#8


to sclzmbie(梦里红尘)

我不理解他的程序,你能给我分析一下吗?

谢谢!

#9


我的想法和one_add_one()快给分给分()一样

#10


 one_add_one和kj_stone的方法都行,只不过one_add_one的方法比较新奇

#11


刚才又看了一遍kj_stone的方法,终于理解了!

哈哈!

#12



哈哈题目给出的数组的总概率超过了一!是无解的!哈哈!
白折腾了!你们!呵呵~~~

#13



感谢大吓们的热情!!!!
先说一下 kj_stone(stone) 的解:
这个解可以把大数的概率取多次,可是有一个问题
不能算出究竟是哪个数,比如在数组a()中,
a(2)和a(8)都是4哪么我算出的这个case究竟是哪个4 呢
是a(2)还是a(8)呢?

one_add_one()快给分给分() 
的方法真有些意思

#14


这个问题大概可以称为权随机问题,准形式化的表达可以是这样:
在n的元素的空间(N1,N2,...,Nn)中,Ni元素的出现次数为Ri(必须为每个元素定义),
普通的随机即为R1 = R2 = ... = Rn 的特殊情况。

算法可以是这样:
定义一个新的样本空间,使元素个数为R1 + R2 + ... + Rn.记为M。使得
M[0] = M[1] = ... M[R1-1] = 1
M[R1] = ... = M[R2-1] = 2
...
M[Ri] = ... = M[R(i+1) - 1 ] = i
...
M[Rn-1] = ...= M[Rn] = n
在这个数组中利用rand()取随机树,k = rand() . 则N[M[Rk]即为结果。
这就是one_add_one()快给分给分()的算法吧。也是我现在想到的唯一的算法.当然优化的办法还有.

#15


用这个公式:

x=[(sqrt(1+8*rnd)-1)/2]+1

简单吧!


我刚刚推出来的,呵呵!

#16


上面的式子中rnd是是你的计算机生成的随机数,rnd<n(n+1)/2。

#17


#inckude(stdio.h)
main()
       {int p[7];
       int i;
START: for(i=1;i<=7;i++)/*给数组赋值 数组从p[1]到p[7] 分别赋以初值1 2 3 4 5 6 7 */
       p[i]=i;
       printf("please input the data/n");
       scanf("%d",&k);
       if(k<0 or k>7)
       printf("error input/n")
       else i=k;
       if(p[i]!=0)printf("%d",i)/*若数组为0,则不输出*/
       p[i]=p[i]-1;/*每输出一个数,使相应的数组减一*/
       while(p[1]=0&&p[2]=0&&p[3]=0&&p[4]=0&&p[5]=0&&p[6]=0&&p[7]=0)goto START
    }是不是很简单??

#18


 大家觉得我的程序是不是能实现上述功能 

#19


编译通不过!

我觉得算法不灵活!

#20


大家好涌跃啊!!!! 感谢感谢


to:wwl_f117(孤独之狼) 
您的程序只有在多次抽取后才有意义,
但我想只抽一次的话就不好使了.

to:one_add_one()快给分给分()
你的公式有一点小问题,当这个数组中的数只出现一次时好用.
但当这个数组中有重复数的时候就有问题了.

现在我把这道题给大家扩展一下:
有一个数据库有两个字段,DATA 和 COUNT

DATA COUNT
A 5
B 8
C 1
D 8
E 6
这个数据库的记录个数是不定的
ID号的生成也是随机的
现在我需要从DATA 随机中取出一个数据
当然这个随机要根据 count 的值来确定出现概率
的大小.

就好象是一个购物抽奖程序, 
DATA 是你的名字, COUNT 是你购物的个数
当然你购物的个数越多,抽奖的机率就越大了.

#21


那就建一个这样的就行了:

{C,A,A,A,A,A,E,E,E,E,E,E,D,D,D,D,D,D,D,D,B,B,B,B,B,B,B,B}

然后再取不就行了?

#22


to:one_add_one()快给分给分()
这是最基本的算法,没什么意思.
我想要有意思一点的算法.

#23


你只是问怎么办,没问有没有意思呀!


那我再想想!

#24


上面的算法有很大的优化余地,一定能满足需要!

你现在是要解决问题,还是要干什么?

#25


当然我的分还是要给的,只不过大家再继续研究出更优秀的作法吗