注册 登录
编程论坛 VFP论坛

没事就折腾一下,各位大大有没有写过一定范围内按比例出随机数?

shonken 发布于 2022-12-14 09:43, 2036 次点击
如:随机0~100的整数,0~30占70%,31~80占10%,81~100占20%这样?
21 回复
#2
吹水佬2022-12-14 10:13
随机0~100的整数要多少个?
#3
hu9jj2022-12-14 10:23
用循环来获取随机数,符合要求的则保留,不符合要求的则放弃不用,直至获得需要数量的随机数。
#4
shonken2022-12-14 11:23
以下是引用吹水佬在2022-12-14 10:13:23的发言:

随机0~100的整数要多少个?


暂没具体的应用场景,可以假设一下

随机0~100的整数,假设需要50个数,其中0~30占70%的机率,31~80占10%的机率,81~100占20%机率,数可以重复。
#5
sam_jiang2022-12-14 11:36
你这是伪随机啊,直接0-30  35个。31-80  5个。剩下的10个!
#6
shonken2022-12-14 11:47
以下是引用sam_jiang在2022-12-14 11:36:49的发言:

你这是伪随机啊,直接0-30  35个。31-80  5个。剩下的10个!


有所侧重,想起一个场景可用,就像汉字库,排前的常用字,排后的生僻字,随机挑选时希望得到常用字多些
#7
sam_jiang2022-12-14 15:15
那我觉得你可以转换思路,建一个表来记录用户的输入习惯,记录用户最常使用的10个字,当用户输入拼音时,调取最常用的10个字。目前市面上流行的输入法都是用这种办法!对于新用户,你只需要按笔画顺序推送候选字就可以了。这种方法非常精准!
#8
cjc10102022-12-14 15:26
s1 取0-100
case s1<=10
   s2 取31-80
case s1>10 and s1<30
   s2 取80-100
other
   s2取0-30
这样可合你意?
#9
shonken2022-12-14 17:33
以下是引用cjc1010在2022-12-14 15:26:38的发言:

s1 取0-100
case s1<=10
   s2 取31-80
case s1>10 and s1<30
   s2 取80-100
other
   s2取0-30
这样可合你意?


差不多这个样子,如果是自定义比例呢?
#10
shonken2022-12-14 17:34
谢谢以上各位大大帮我理清思路

交个作业

程序代码:

clea
nMin1 = 31
nMax1 = 80
nMin2 = 81
nMax2 = 100
nMin3 = 0
nMax3 = 30
nResult = 0
lcResult = ""
For i = 0 To 100
    nRang = Int((100 - 0 + 1) * Rand( ) + 0)

    Do Case
        Case nRang <=10
            nResult = Int((nMax1 - nMin1 + 1) * Rand( ) + nMin1)
        Case Between(nRang,11,30)
            nResult = Int((nMax2 - nMin2 + 1) * Rand( ) + nMin2)
        Otherwise
            nResult = Int((nMax3 - nMin3 + 1) * Rand( ) + nMin3)
    Endcase
    lcResult = lcResult + Transform(nResult)+","
Endfor
?lcResult
#11
吹水佬2022-12-14 17:51
回复 10楼 shonken
好象没见到那些:70%、10%、20%
#12
shonken2022-12-14 18:21
回复 11楼 吹水佬
case那里,但好像不能准确表达自定义比例
#13
shonken2022-12-14 18:41
弄成函数

程序代码:

Clea
nMin1 = 31&&比例1的最小值范围
nMax1 = 80&&比例1的最大值范围
nMin2 = 81
nMax2 = 100
nMin3 = 0
nMax3 = 30
nRang1 = 20 &&比例1
nRang2 = 10 &&比例2
?x_RandRang(nRang1,nMin1,nMax1,nRang2,nMin2,nMax2,nMin3,nMax3)

Function x_RandRang(nRang1,nMin1,nMax1,nRang2,nMin2,nMax2,nMin3,nMax3)
    nResult = 0
    lcResult = ""
    For i = 0 To 100
        nRang = Int((100 - 0 + 1) * Rand( ) + 0)
        Do Case
            Case nRang <= nRang1
                nResult = Int((nMax1 - nMin1 + 1) * Rand( ) + nMin1)
            Case Between(nRang,nRang1 + 1 ,nRang1 + nRang2)
                nResult = Int((nMax2 - nMin2 + 1) * Rand( ) + nMin2)
            Otherwise
                nResult = Int((nMax3 - nMin3 + 1) * Rand( ) + nMin3)
        Endcase
        lcResult = lcResult + Transform(nResult)+","
    Endfor
    Return lcResult
Endfunc

#14
吹水佬2022-12-14 19:52
占比不是这样子的吧
试将结果按占比要求统计一下
我看每次结果也不会一样
#15
sam_jiang2022-12-15 00:19
***改成函数吧,代码如下:***
***win7,foxpro9.0下编译通过***
myrand(30,80,99,70,10,20)
Function myrand
parameter num1,num2,num3,percent1,percent2,percent3
local x,y,z,cstr
store 0 to x,y,z
cstr=''
do while .t.
n=int(rand()*100)
if n<=num1
    x=x+1
    if x<=percent1
        cstr=cstr+transform(n)+';'
        loop
    endif
    loop
endif
if n<=num2
    y=y+1
    if y<=percent2
        cstr=cstr+transform(n)+';'
        loop
    endif
    loop
endif
if n<=num3
    z=z+1
    if z<=percent3
        cstr=cstr+transform(n)+';'
        loop
    endif
    if x>percent1 and y>percent2 and z>percent3
        exit&&确保完成任务再退出
    else
         loop
    endif
endif
enddo
?cstr
endfunc
***myrand(30,80,99, 70,10,20)***
***正好100个数***

[此贴子已经被作者于2022-12-16 14:43编辑过]

#16
DBFuser2022-12-15 23:25
如果搞彩票的这样干……
#17
hu9jj2022-12-16 09:04
5楼坛友的方法不错,思路更清晰!
#18
吹水佬2022-12-16 11:41
以下是引用hu9jj在2022-12-16 09:04:25的发言:

5楼坛友的方法不错,思路更清晰!

就是,既然可重复,直接随机抽够数就可以
#19
sam_jiang2022-12-16 14:37
回复 16楼 DBFuser
最佳应用场景是某某公司的年会抽奖环节,所谓的内定抽奖。
#20
sam_jiang2022-12-16 19:43
***逻辑顺序重新优化一下,用case...endcase估计可以更加有效率***
***感兴趣的可以再优化一下***
myrand(30,80,99, 70,10,20)
function myrand
parameters num1,num2,num3,percent1,percent2,percent3
local x,y,z,cstr
store 0 to x,y,z
cstr=''
clea
do while .t.
n=int(rand()*100)
if x>=percent1 and y>=percent2 and z>=percent3
    exit&&确保完成任务再退出
else
    if n<=num1
        x=x+1
        if x<=percent1
            cstr=cstr+transform(n)+';'
            loop
        endif
           loop
    endif
    if n<=num2
        y=y+1
        if y<=percent2
            cstr=cstr+transform(n)+';'
            loop
        endif
        loop
    endif
    if n<=num3
        z=z+1
        if z<=percent3
            cstr=cstr+transform(n)+';'
            loop
        endif
        loop
    endif
endif
enddo
?cstr
ENDFUNC
***myrand(30,80,99, 70,10,20)***
***正好100个数***
#21
mywisdom882022-12-17 08:02
以下是引用shonken在2022-12-14 09:43:38的发言:

如:随机0~100的整数,0~30占70%,31~80占10%,81~100占20%这样?

好像是可以这样做
1.取各段的数量
段1 = int(总数) * 0.7
段2 = int(总数) * 0.1
段3 = int(总数) * 0.2
或者这样
段2 = int(总数) * 0.1
段3 = int(总数) * 0.2
段1 = 总数 - 段2 - 段3
2.用循环分别取对应的段位的随机数
我记得,好像可以这样的
*0~30段位
for i=1 to 30
?int(rand()*30)
endfor
*31~80段位
for i=1 to 80
?int(rand()*50)+30
*81~100段位
for i=1 to 20
?int(rand()*20)+80
endfor



[此贴子已经被作者于2022-12-17 08:14编辑过]

#22
cssnet2022-12-17 08:38
创建一个表dbfInt.dbf,就一个整型数字段aint。
或者,定义一个数组Dime aint[1000]
生成1000个数值在要求范围以内的随机数,必要时,生成1万个也行。

=rand(-1)
for i=1 to 1000
    lnInt = int(rand()*100)
    insert into dbfInt (aint) value (lnInt)
endfor i

然后,自上而下,往后扫描这张表,取到合适的,0--30,就留下,不合适的跳过,至取满所需个数;
继续,从下一条记录开始,往后扫描这张表,取到合适的,31--70,就留下,不合适的跳过,至取满所需个数;
继续,从下一条记录开始,往后扫描这张表,取到合适的,71--100,就留下,不合适的跳过,至取满所需个数。
……全剧终。
1