用于生成随机单词组合的功能

时间:2015-02-25 07:53:34

标签: asp-classic

我有一个MySQL数据库表,其中包含6,318个随机单词。

我有一些代码可以从该表中进行选择,并将这些单词放入数组中。

我写了一个函数来提取一组字母长的随机单词组合 - 例如8个字符。

我遇到的问题是该功能似乎不是随机的。由于表中有6,318个单词,我知道有数百个单词组合长度为8个字符,但我发现代码的输出通常会重复相同的组合。

这是代码:

<%

SQL1 = "SELECT fld_un FROM j_un2 ORDER BY rand()"

'##############################################################################

set p1RS = oConn.Execute(SQL1)
list1 = p1RS.GetRows
p1RS.Close

block1 = ""
For row = 0 to UBound(list1,2)
 block1 = block1 & list1(0,row) & ","
next
Erase list1

wordArray1 = split(block1, ",")

Function f1(str)
    found = "no"
    max=6138
    min = 1
    do while found <> "yes"
        Randomize
        rand1 = Int((max-min+1)*Rnd+min)
        rand2 = Int((max-min+1)*Rnd+min)
        word = wordArray1(rand1) & wordArray1(rand2)
        if len(word) = str + 1 then 
            found = "yes"
            f1 = word
        end if
    Loop
End Function

for i = 1 to 10
    bob = f1(8)
    response.write bob & "<br />"
next
%>

示例输出:

shootnail
epeestove
buggersix
splatsane
urbanbash
pinevital
shootnail
epeestove
buggersix
splatsane

如您所见,某些组合会重复 - 例如从上面的摘录中,只有这两种组合是唯一的:

urbanbash
pinevital

如果我这样做(例如输出20):

for i = 1 to 20
    bob = f1(8)
    response.write bob & "<br />"
next

然后,这些组合都不是唯一的:

raftsniff
hitactive
nineridge
tartmagma
turnbuyer
klutzpity
adoptlose
bookspell
herbshare
raftsniff
hitactive
nineridge
tartmagma
turnbuyer
klutzpity
adoptlose
bookspell
herbshare
raftsniff
hitactive

我错过了一些明显的东西 - 我无法弄清楚为什么这些组合会像他们一样重复。

1 个答案:

答案 0 :(得分:0)

这里的问题是您在使用Randomize()时可能从互联网上的其他示例中汲取的误解。

Randomize做什么?

Randomize()的工作原理是生成一个种子值,默认情况下取自系统时间(因为这会不断改变结果应始终是随机的)。然后Rnd()使用此种子生成随机值。

那么问题是什么?

Randomize()放置在一个可以每秒多次计算的循环中时,它实际上会重新生成具有相同值的种子。

和解决方案?

由于Randomize()Rnd()提供初始种子然后使用,因此没有理由在执行代码中多次调用它。在Classic ASP页面顶部调用一次Randomize()函数足以为Rnd()设置值,然后使用任何代码(循环或其他)

要解决问题中的特定问题,请将Randomize()完全取出代码中的任何循环并将其放置在(最好靠近页面顶部)以设置随机种子一次。

问题中的例子看起来应该是这样的;

<%
'Call Randomize() once to set the seed for the page.
Randomize
SQL1 = "SELECT fld_un FROM j_un2 ORDER BY rand()"

'##############################################################################

set p1RS = oConn.Execute(SQL1)
list1 = p1RS.GetRows
p1RS.Close

block1 = ""
For row = 0 to UBound(list1,2)
 block1 = block1 & list1(0,row) & ","
next
Erase list1

wordArray1 = split(block1, ",")

'Removed Randomize() from the f1() function, Rnd() will now use the
'seeded value set at the beginning of the code.
Function f1(str)
    found = "no"
    max=6138
    min = 1
    do while found <> "yes"
        rand1 = Int((max-min+1)*Rnd+min)
        rand2 = Int((max-min+1)*Rnd+min)
        word = wordArray1(rand1) & wordArray1(rand2)
        if len(word) = str + 1 then 
            found = "yes"
            f1 = word
        end if
    Loop
End Function

for i = 1 to 10
    bob = f1(8)
    response.write bob & "<br />"
next
%>

有用的链接