VB问题中的非重复随机数生成器

时间:2015-10-16 14:01:35

标签: arrays vb.net

我似乎无法弄清楚如何在数组中生成非重复随机数。我已尝试使用do循环,如果值已经在数组中,它应该在该位置重新分配一个新的随机数,直到该数字不再在数组中,并且它一直有效,直到第三次或第四次运行。这就是我现在所拥有的:

Module Lab4_Lottery

Sub Main()

    Dim wins(9) As Integer
    For m = 0 To 9
        wins(m) = -1 ' Initialized to -1 to distinguish elements that have not been given lottery numbers yet
    Next m

    Dim numsSoFar As Integer = 0 ' Counter variable
    Dim temp As Integer = 0 ' Random number holder
    Dim r As New Random
    Dim userInput As Integer

    While numsSoFar < 10


        Dim flag As Boolean = False
        temp = r.Next(100)



        If wins(numsSoFar) = temp Then

            flag = True

            Do      ' Here, the do loop should've generated a random number 
                temp = r.Next(100)      ' that wasn't already in the array
                wins(numsSoFar) = temp

            Loop Until temp <> wins(numsSoFar)

        End If

        If flag = False Then

            wins(numsSoFar) = temp

        End If




        Console.Write(temp & " ") ' Testing purposes to see if numbers are being repeated
        numsSoFar += 1
        flag = False


    End While


    Console.WriteLine("Please enter your lottery number")
    userInput = Console.ReadLine()

    Dim blnFound As Boolean = False
    numsSoFar = 0

    Do While Not blnFound And numsSoFar < wins.Length

        If userInput = wins(numsSoFar) Then
            blnFound = True
        End If

        numsSoFar += 1

    Loop

    If blnFound Then

        Console.WriteLine("Congratulations! You won the lottery!")

    Else

        Console.WriteLine("Sorry, you lose. Better luck next time!")

    End If

    For i As Integer = 0 To 9

        Console.Write(wins(i) & " ")

    Next i

End Sub

结束模块

3 个答案:

答案 0 :(得分:1)

听起来你想要100个池中的10个数字,没有重复。这涉及到一个Shuffle。这是一个简单的方法:

isEmailTaken?

对于下一张图,只需重新洗牌并再次拍摄10张。洗牌很简单:

else

标准的Fisher-Yates shuffle是每个程序员至少应该知道的东西。它非常高效和快速。作为替代方案,在许多情况下,这会产生足够好的洗牌:

' an array of all possible values 1-100
Dim Lotto As Int32() = Enumerable.Range(1, 100).ToArray()

' shuffle the array to a random order
Shuffle(Lotto)

' pick 10 winning numbers for this drawing:
Dim winners = Lotto.Take(10).ToArray()

您也可以将它们粘合在一起:

' class level random object
Private myRand As New Random()
' std Fisher-Yates shuffle
Private Sub Shuffle(arry() As Integer)
    Dim tmp As Integer
    Dim j As Integer

    For n As Integer = arry.Length - 1 To 0 Step -1
        j = myRand.Next(0, n + 1)             
        tmp = arry(j)

        ' swap item(j) and item(n) 
        arry(j) = arry(n)
        arry(n) = tmp
    Next
End Sub

与另一个答案中的建议相反,每次创建一个新的Lotto = Lotto.OrderBy(Function(r) myRand.Next).ToArray() 对象是一个非常糟糕的想法,特别是在循环中 - 这是一种确保你重复一遍。你也不需要提供种子。

答案 1 :(得分:0)

Do      ' Here, the do loop should've generated a random number 
    temp = r.Next(100)      ' that wasn't already in the array
    wins(numsSoFar) = temp

Loop Until temp <> wins(numsSoFar)

此循环仅检查数组中的 last 数字是否匹配。即使这个循环嵌套在另一个遍历数组中每个数字的循环中,这也不足以检查重复的每个数字。如上所述,它只会阻止连续的数字匹配。要修复它,我会将最后一行更改为:

Loop Until Array.IndexOf(wins, temp) > -1

答案 2 :(得分:0)

您必须使用新种子创建一个新的随机实例,就像下面的示例

一样
    For index = 1 To 1000
        Dim r = New Random(Guid.NewGuid().GetHashCode())
        Dim randomNumber = r.Next(100)
        Console.WriteLine(randomNumber)
    Next

    Console.ReadKey()