比如 在100里面读取不重复的随机数。
我的做法是,创建一个递归。
然后执行,读取一个随机数。然后判断是否读取过,如果没有,就把这个数字保存在数组中,然后把计数器+1
然后继续执行,直到计数器达到指定的数字退出。
不过这样的程序,循环次数不定。有的时候循环多,有的时候循环少,多的时候,很容易造成堆栈溢出。
有没有什么更优化的办法呀。
6 个解决方案
#1
<SCRIPT LANGUAGE=vbscript >
'洗牌
Dim N,S,D,P
P=54'牌的数量
Set D = CreateObject("Scripting.Dictionary")
do while D.Count<P
Randomize
N=Int(P * Rnd + 1)
if not D.Exists(cstr(N)) then
D.Add cstr(N),cstr(N)
end if
loop
for each K in D.Keys
S=S & K & " "
next
msgbox replace(trim(S)," ",",")
</SCRIPT>
'洗牌
Dim N,S,D,P
P=54'牌的数量
Set D = CreateObject("Scripting.Dictionary")
do while D.Count<P
Randomize
N=Int(P * Rnd + 1)
if not D.Exists(cstr(N)) then
D.Add cstr(N),cstr(N)
end if
loop
for each K in D.Keys
S=S & K & " "
next
msgbox replace(trim(S)," ",",")
</SCRIPT>
#2
100里面读取不重复的随机数?
读取的个数随便定义?
那100里面读取101个不重复的随机数,当然是死循环了,递归死了啊
不知道
superdullwolf(超级大笨狼,每天要自强) 的'洗牌用来干什么的
读取的个数随便定义?
那100里面读取101个不重复的随机数,当然是死循环了,递归死了啊
不知道
superdullwolf(超级大笨狼,每天要自强) 的'洗牌用来干什么的
#3
aID="1|23|44|55|56|57|77|88|99|33"..............
这个形式的字符串。一般大约100个数字左右。
aNum=40 '从上面的数字里面取出来的数字量
makeID aID,aNum,0 '调用
sub makeID(aID,aNum,tt)
if tt=anum then exit sub '如果读取的数量=要求的数量,推出递归
x=0
nID=aid
nid=split(nID,"|")
randomize
i = cint(rnd(ubound(nID))*ubound(nID)) '随机读取nid这个数组的编号
if instr(ai,"|"&i&"|")=0 then '判断是否随机过这个数字
if nid(i)<>"" then
tid=tID & nid(i) & "|" '将这个数字保存在tid的变量中
ai=ai & "||" & i & "|" '将随机出来的数字保存在ai中
x=1
end if
end if
makeid aid,anum,tt+x '继续调用
end sub
这段程序是放在asp中运行。程序没问题,不过读取数字少的时候没问题。 一旦多了就出现堆栈溢出。我都晕死了。 如果放在客户端就不会有这个问题了。现在放在服务器段运行这个程序运行时间长了,就溢出了。我想找一个更加简单的方法来随机数字出来。
或者更加省资源的算法。 不知道这个东西如果写在存储过程中会不会有问题。
这个形式的字符串。一般大约100个数字左右。
aNum=40 '从上面的数字里面取出来的数字量
makeID aID,aNum,0 '调用
sub makeID(aID,aNum,tt)
if tt=anum then exit sub '如果读取的数量=要求的数量,推出递归
x=0
nID=aid
nid=split(nID,"|")
randomize
i = cint(rnd(ubound(nID))*ubound(nID)) '随机读取nid这个数组的编号
if instr(ai,"|"&i&"|")=0 then '判断是否随机过这个数字
if nid(i)<>"" then
tid=tID & nid(i) & "|" '将这个数字保存在tid的变量中
ai=ai & "||" & i & "|" '将随机出来的数字保存在ai中
x=1
end if
end if
makeid aid,anum,tt+x '继续调用
end sub
这段程序是放在asp中运行。程序没问题,不过读取数字少的时候没问题。 一旦多了就出现堆栈溢出。我都晕死了。 如果放在客户端就不会有这个问题了。现在放在服务器段运行这个程序运行时间长了,就溢出了。我想找一个更加简单的方法来随机数字出来。
或者更加省资源的算法。 不知道这个东西如果写在存储过程中会不会有问题。
#4
那么 Dictionary.Exists 方法的原理呢?会不会还是使用循环的方法的?
如果 Exists 本身就是用循环实现的,那么在效率上应该没有提高的吧?
如果 Exists 本身就是用循环实现的,那么在效率上应该没有提高的吧?
#5
我是这么想的。方法并不一定好。
思想就是预先准备好一个“数字池”,抽取一点,就拿掉一个;
然后继续在剩下的数字中随机抽取。
直接在浏览器测试。
<script language="VBScript">
'随机数的最大数
n=100
'要取的随机数个数
t=10
dim z(99)
dim x(19)
for i=Lbound(z) to UBound(z)
z(i)=i+1
next
if t<=n then
Randomize
for i=LBound(x) to UBound(x)
l=Int(rnd*n)
x(i)=z(l)
for j=l to n-2
z(j)=z(j+1)
next
n=n-1
next
end if
aaa = "|"
for i=LBound(x) to UBound(x)
aaa = aaa & x(i) & "|"
next
msgbox aaa,64,""
</script>
楼主的方法当需要抽取的数字个数比较大甚至接近数字总数的时候,
会频繁的抽取到已经抽取过的数字,所以有可能造成循环次数很多。
我这里的方法虽然循环的次数也很多,但是,是有可靠性的,
而且,需要抽取的数字个数越多(当然不能超过数字总数),优势越明显。
思想就是预先准备好一个“数字池”,抽取一点,就拿掉一个;
然后继续在剩下的数字中随机抽取。
直接在浏览器测试。
<script language="VBScript">
'随机数的最大数
n=100
'要取的随机数个数
t=10
dim z(99)
dim x(19)
for i=Lbound(z) to UBound(z)
z(i)=i+1
next
if t<=n then
Randomize
for i=LBound(x) to UBound(x)
l=Int(rnd*n)
x(i)=z(l)
for j=l to n-2
z(j)=z(j+1)
next
n=n-1
next
end if
aaa = "|"
for i=LBound(x) to UBound(x)
aaa = aaa & x(i) & "|"
next
msgbox aaa,64,""
</script>
楼主的方法当需要抽取的数字个数比较大甚至接近数字总数的时候,
会频繁的抽取到已经抽取过的数字,所以有可能造成循环次数很多。
我这里的方法虽然循环的次数也很多,但是,是有可靠性的,
而且,需要抽取的数字个数越多(当然不能超过数字总数),优势越明显。
#6
搞定。多谢各位关注。
原来思路一开始就错了。
exam=rse.fields("exam_question") '读取考试题目,存储类似于1|2|3|4|5|6|这样的形式
total_num=rse.fields("exam_mark")
exam=split(exam,"|")
question="|"
mark=0
AI="|"
ssQ=rse.fields("ssQ") '读取题目数量
smQ=rse.fields("smQ")
ynQ=rse.fields("ynQ")
lsQ=rse.fields("lsq")
for i=0 to ubound(exam)-1
set rsType=server.createobject("adodb.recordset")
mysql="select id,Question_type from Exam_question where id =" & exam(i)
rsType.open mysql,econn,1,1
select case rsType.fields("question_type")
case 1
smID = smID & exam(i) & "|"
case 2
ssID = ssID & exam(i) & "|"
case 3
ynID = ynID & exam(i) & "|"
case 4
lsID = lsID & exam(i) & "|"
end select
rsType.close
set rsType=nothing
next
sm=split(smID,"|")
smnum=ubound(sm)
i=0
for i = 0 to 2*smNum
randomize
j=fix(rnd*smNum)
k=fix(rnd*smNum)
temp=sm(j)
sm(j)=sm(k)
sm(k)=temp
next
i=0
for i =0 to smQ-1
mu=mu & sm(i) & "|"
next
ss=split(ssID,"|")
ssnum=ubound(ss)
for i = 0 to 2*ssNum
randomize
j=fix(rnd*ssNum)
k=fix(rnd*ssNum)
temp=ss(j)
ss(j)=ss(k)
ss(k)=temp
next
i =0
for i =0 to ssQ-1
si=si & ss(i) & "|"
next
yy=split(ynID,"|")
ynnum=ubound(yy)
for i = 0 to 2*ynNum
randomize
j=fix(rnd*ynNum)
k=fix(rnd*ynNum)
temp=yy(j)
yy(j)=yy(k)
yy(k)=temp
next
i =0
for i =0 to ynQ-1
yn=yn & yy(i) & "|"
next
ll=split(lsID,"|")
lsnum=ubound(ll)
for i = 0 to 2*lsNum
randomize
j=fix(rnd*lsNum)
k=fix(rnd*lsNum)
temp=ll(j)
ll(j)=ll(k)
ll(k)=temp
next
i =0
for i =0 to lsQ-1
ls=ls & ll(i) & "|"
next
原来思路一开始就错了。
exam=rse.fields("exam_question") '读取考试题目,存储类似于1|2|3|4|5|6|这样的形式
total_num=rse.fields("exam_mark")
exam=split(exam,"|")
question="|"
mark=0
AI="|"
ssQ=rse.fields("ssQ") '读取题目数量
smQ=rse.fields("smQ")
ynQ=rse.fields("ynQ")
lsQ=rse.fields("lsq")
for i=0 to ubound(exam)-1
set rsType=server.createobject("adodb.recordset")
mysql="select id,Question_type from Exam_question where id =" & exam(i)
rsType.open mysql,econn,1,1
select case rsType.fields("question_type")
case 1
smID = smID & exam(i) & "|"
case 2
ssID = ssID & exam(i) & "|"
case 3
ynID = ynID & exam(i) & "|"
case 4
lsID = lsID & exam(i) & "|"
end select
rsType.close
set rsType=nothing
next
sm=split(smID,"|")
smnum=ubound(sm)
i=0
for i = 0 to 2*smNum
randomize
j=fix(rnd*smNum)
k=fix(rnd*smNum)
temp=sm(j)
sm(j)=sm(k)
sm(k)=temp
next
i=0
for i =0 to smQ-1
mu=mu & sm(i) & "|"
next
ss=split(ssID,"|")
ssnum=ubound(ss)
for i = 0 to 2*ssNum
randomize
j=fix(rnd*ssNum)
k=fix(rnd*ssNum)
temp=ss(j)
ss(j)=ss(k)
ss(k)=temp
next
i =0
for i =0 to ssQ-1
si=si & ss(i) & "|"
next
yy=split(ynID,"|")
ynnum=ubound(yy)
for i = 0 to 2*ynNum
randomize
j=fix(rnd*ynNum)
k=fix(rnd*ynNum)
temp=yy(j)
yy(j)=yy(k)
yy(k)=temp
next
i =0
for i =0 to ynQ-1
yn=yn & yy(i) & "|"
next
ll=split(lsID,"|")
lsnum=ubound(ll)
for i = 0 to 2*lsNum
randomize
j=fix(rnd*lsNum)
k=fix(rnd*lsNum)
temp=ll(j)
ll(j)=ll(k)
ll(k)=temp
next
i =0
for i =0 to lsQ-1
ls=ls & ll(i) & "|"
next
#1
<SCRIPT LANGUAGE=vbscript >
'洗牌
Dim N,S,D,P
P=54'牌的数量
Set D = CreateObject("Scripting.Dictionary")
do while D.Count<P
Randomize
N=Int(P * Rnd + 1)
if not D.Exists(cstr(N)) then
D.Add cstr(N),cstr(N)
end if
loop
for each K in D.Keys
S=S & K & " "
next
msgbox replace(trim(S)," ",",")
</SCRIPT>
'洗牌
Dim N,S,D,P
P=54'牌的数量
Set D = CreateObject("Scripting.Dictionary")
do while D.Count<P
Randomize
N=Int(P * Rnd + 1)
if not D.Exists(cstr(N)) then
D.Add cstr(N),cstr(N)
end if
loop
for each K in D.Keys
S=S & K & " "
next
msgbox replace(trim(S)," ",",")
</SCRIPT>
#2
100里面读取不重复的随机数?
读取的个数随便定义?
那100里面读取101个不重复的随机数,当然是死循环了,递归死了啊
不知道
superdullwolf(超级大笨狼,每天要自强) 的'洗牌用来干什么的
读取的个数随便定义?
那100里面读取101个不重复的随机数,当然是死循环了,递归死了啊
不知道
superdullwolf(超级大笨狼,每天要自强) 的'洗牌用来干什么的
#3
aID="1|23|44|55|56|57|77|88|99|33"..............
这个形式的字符串。一般大约100个数字左右。
aNum=40 '从上面的数字里面取出来的数字量
makeID aID,aNum,0 '调用
sub makeID(aID,aNum,tt)
if tt=anum then exit sub '如果读取的数量=要求的数量,推出递归
x=0
nID=aid
nid=split(nID,"|")
randomize
i = cint(rnd(ubound(nID))*ubound(nID)) '随机读取nid这个数组的编号
if instr(ai,"|"&i&"|")=0 then '判断是否随机过这个数字
if nid(i)<>"" then
tid=tID & nid(i) & "|" '将这个数字保存在tid的变量中
ai=ai & "||" & i & "|" '将随机出来的数字保存在ai中
x=1
end if
end if
makeid aid,anum,tt+x '继续调用
end sub
这段程序是放在asp中运行。程序没问题,不过读取数字少的时候没问题。 一旦多了就出现堆栈溢出。我都晕死了。 如果放在客户端就不会有这个问题了。现在放在服务器段运行这个程序运行时间长了,就溢出了。我想找一个更加简单的方法来随机数字出来。
或者更加省资源的算法。 不知道这个东西如果写在存储过程中会不会有问题。
这个形式的字符串。一般大约100个数字左右。
aNum=40 '从上面的数字里面取出来的数字量
makeID aID,aNum,0 '调用
sub makeID(aID,aNum,tt)
if tt=anum then exit sub '如果读取的数量=要求的数量,推出递归
x=0
nID=aid
nid=split(nID,"|")
randomize
i = cint(rnd(ubound(nID))*ubound(nID)) '随机读取nid这个数组的编号
if instr(ai,"|"&i&"|")=0 then '判断是否随机过这个数字
if nid(i)<>"" then
tid=tID & nid(i) & "|" '将这个数字保存在tid的变量中
ai=ai & "||" & i & "|" '将随机出来的数字保存在ai中
x=1
end if
end if
makeid aid,anum,tt+x '继续调用
end sub
这段程序是放在asp中运行。程序没问题,不过读取数字少的时候没问题。 一旦多了就出现堆栈溢出。我都晕死了。 如果放在客户端就不会有这个问题了。现在放在服务器段运行这个程序运行时间长了,就溢出了。我想找一个更加简单的方法来随机数字出来。
或者更加省资源的算法。 不知道这个东西如果写在存储过程中会不会有问题。
#4
那么 Dictionary.Exists 方法的原理呢?会不会还是使用循环的方法的?
如果 Exists 本身就是用循环实现的,那么在效率上应该没有提高的吧?
如果 Exists 本身就是用循环实现的,那么在效率上应该没有提高的吧?
#5
我是这么想的。方法并不一定好。
思想就是预先准备好一个“数字池”,抽取一点,就拿掉一个;
然后继续在剩下的数字中随机抽取。
直接在浏览器测试。
<script language="VBScript">
'随机数的最大数
n=100
'要取的随机数个数
t=10
dim z(99)
dim x(19)
for i=Lbound(z) to UBound(z)
z(i)=i+1
next
if t<=n then
Randomize
for i=LBound(x) to UBound(x)
l=Int(rnd*n)
x(i)=z(l)
for j=l to n-2
z(j)=z(j+1)
next
n=n-1
next
end if
aaa = "|"
for i=LBound(x) to UBound(x)
aaa = aaa & x(i) & "|"
next
msgbox aaa,64,""
</script>
楼主的方法当需要抽取的数字个数比较大甚至接近数字总数的时候,
会频繁的抽取到已经抽取过的数字,所以有可能造成循环次数很多。
我这里的方法虽然循环的次数也很多,但是,是有可靠性的,
而且,需要抽取的数字个数越多(当然不能超过数字总数),优势越明显。
思想就是预先准备好一个“数字池”,抽取一点,就拿掉一个;
然后继续在剩下的数字中随机抽取。
直接在浏览器测试。
<script language="VBScript">
'随机数的最大数
n=100
'要取的随机数个数
t=10
dim z(99)
dim x(19)
for i=Lbound(z) to UBound(z)
z(i)=i+1
next
if t<=n then
Randomize
for i=LBound(x) to UBound(x)
l=Int(rnd*n)
x(i)=z(l)
for j=l to n-2
z(j)=z(j+1)
next
n=n-1
next
end if
aaa = "|"
for i=LBound(x) to UBound(x)
aaa = aaa & x(i) & "|"
next
msgbox aaa,64,""
</script>
楼主的方法当需要抽取的数字个数比较大甚至接近数字总数的时候,
会频繁的抽取到已经抽取过的数字,所以有可能造成循环次数很多。
我这里的方法虽然循环的次数也很多,但是,是有可靠性的,
而且,需要抽取的数字个数越多(当然不能超过数字总数),优势越明显。
#6
搞定。多谢各位关注。
原来思路一开始就错了。
exam=rse.fields("exam_question") '读取考试题目,存储类似于1|2|3|4|5|6|这样的形式
total_num=rse.fields("exam_mark")
exam=split(exam,"|")
question="|"
mark=0
AI="|"
ssQ=rse.fields("ssQ") '读取题目数量
smQ=rse.fields("smQ")
ynQ=rse.fields("ynQ")
lsQ=rse.fields("lsq")
for i=0 to ubound(exam)-1
set rsType=server.createobject("adodb.recordset")
mysql="select id,Question_type from Exam_question where id =" & exam(i)
rsType.open mysql,econn,1,1
select case rsType.fields("question_type")
case 1
smID = smID & exam(i) & "|"
case 2
ssID = ssID & exam(i) & "|"
case 3
ynID = ynID & exam(i) & "|"
case 4
lsID = lsID & exam(i) & "|"
end select
rsType.close
set rsType=nothing
next
sm=split(smID,"|")
smnum=ubound(sm)
i=0
for i = 0 to 2*smNum
randomize
j=fix(rnd*smNum)
k=fix(rnd*smNum)
temp=sm(j)
sm(j)=sm(k)
sm(k)=temp
next
i=0
for i =0 to smQ-1
mu=mu & sm(i) & "|"
next
ss=split(ssID,"|")
ssnum=ubound(ss)
for i = 0 to 2*ssNum
randomize
j=fix(rnd*ssNum)
k=fix(rnd*ssNum)
temp=ss(j)
ss(j)=ss(k)
ss(k)=temp
next
i =0
for i =0 to ssQ-1
si=si & ss(i) & "|"
next
yy=split(ynID,"|")
ynnum=ubound(yy)
for i = 0 to 2*ynNum
randomize
j=fix(rnd*ynNum)
k=fix(rnd*ynNum)
temp=yy(j)
yy(j)=yy(k)
yy(k)=temp
next
i =0
for i =0 to ynQ-1
yn=yn & yy(i) & "|"
next
ll=split(lsID,"|")
lsnum=ubound(ll)
for i = 0 to 2*lsNum
randomize
j=fix(rnd*lsNum)
k=fix(rnd*lsNum)
temp=ll(j)
ll(j)=ll(k)
ll(k)=temp
next
i =0
for i =0 to lsQ-1
ls=ls & ll(i) & "|"
next
原来思路一开始就错了。
exam=rse.fields("exam_question") '读取考试题目,存储类似于1|2|3|4|5|6|这样的形式
total_num=rse.fields("exam_mark")
exam=split(exam,"|")
question="|"
mark=0
AI="|"
ssQ=rse.fields("ssQ") '读取题目数量
smQ=rse.fields("smQ")
ynQ=rse.fields("ynQ")
lsQ=rse.fields("lsq")
for i=0 to ubound(exam)-1
set rsType=server.createobject("adodb.recordset")
mysql="select id,Question_type from Exam_question where id =" & exam(i)
rsType.open mysql,econn,1,1
select case rsType.fields("question_type")
case 1
smID = smID & exam(i) & "|"
case 2
ssID = ssID & exam(i) & "|"
case 3
ynID = ynID & exam(i) & "|"
case 4
lsID = lsID & exam(i) & "|"
end select
rsType.close
set rsType=nothing
next
sm=split(smID,"|")
smnum=ubound(sm)
i=0
for i = 0 to 2*smNum
randomize
j=fix(rnd*smNum)
k=fix(rnd*smNum)
temp=sm(j)
sm(j)=sm(k)
sm(k)=temp
next
i=0
for i =0 to smQ-1
mu=mu & sm(i) & "|"
next
ss=split(ssID,"|")
ssnum=ubound(ss)
for i = 0 to 2*ssNum
randomize
j=fix(rnd*ssNum)
k=fix(rnd*ssNum)
temp=ss(j)
ss(j)=ss(k)
ss(k)=temp
next
i =0
for i =0 to ssQ-1
si=si & ss(i) & "|"
next
yy=split(ynID,"|")
ynnum=ubound(yy)
for i = 0 to 2*ynNum
randomize
j=fix(rnd*ynNum)
k=fix(rnd*ynNum)
temp=yy(j)
yy(j)=yy(k)
yy(k)=temp
next
i =0
for i =0 to ynQ-1
yn=yn & yy(i) & "|"
next
ll=split(lsID,"|")
lsnum=ubound(ll)
for i = 0 to 2*lsNum
randomize
j=fix(rnd*lsNum)
k=fix(rnd*lsNum)
temp=ll(j)
ll(j)=ll(k)
ll(k)=temp
next
i =0
for i =0 to lsQ-1
ls=ls & ll(i) & "|"
next