生成随机单词组合的函数

Function to generate random word combinations

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

我有一些代码可以根据 table 执行 select,然后将单词放入数组中。

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

我遇到的问题是函数似乎不是那么随机。由于 table 中有 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
%>

示例输出:

射钉
埃佩斯炉
buggersix
啪啪啪
都市狂欢
松树
射钉
埃佩斯炉
buggersix
啪啪啪

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

都市狂欢
松树

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

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

那么 none 个组合是唯一的:

筏嗅
命中率
九岭
酸岩浆
转买者
笨手笨脚
认输
书咒
草药份额
筏嗅
命中率
九岭
酸岩浆
转买者
笨手笨脚
认输
书咒
草药份额
筏嗅
命中率

我是否遗漏了一些明显的东西 - 我无法理解为什么这些组合会像现在这样重复。

这里的问题是您在使用 Randomize() 时可能从 Internet 上的其他示例中得到的误解。

随机化有什么作用?

Randomize() 通过生成默认取自系统时间的种子值来工作 (因为这是不断变化的,结果应该始终是随机的)。然后 Rnd() 使用此种子生成随机值。

那么问题是什么?

Randomize() 被放置在一个可以每秒计算多次的循环中时,它实际上会重新设定相同的值。

以及解决方案?

由于 Randomize()Rnd() 提供了初始种子,因此没有理由在执行代码中多次调用它。在经典 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
%>

有用的链接

  • SO - VBScript generating same random number when in loop - how to solve?