VB.NET - 从随机数生成器中删除一个数字

时间:2010-05-13 01:23:43

标签: vb.net random

我正在尝试创建一个彩票模拟器。彩票有6个数字,生成的数字必须介于1 - 49之间,并且不能生成下一个数字。我尝试过使用OR功能,但我不确定我是否正确使用它。任何帮助都会很棒。感谢。

Public Class Form1

Private Sub cmdRun_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRun.Click
    ''#Creates a new Random class in VB.NET
    Dim RandomClass As New Random()



    ''####################################
    Dim RandomNumber1 As Integer
    RandomNumber1 = RandomClass.Next(1, 49)
    ''#Displays first number generated
    txtFirst.Text = (RandomNumber1)



    ''####################################
    Dim RandomNumber2 As Integer
    RandomNumber2 = RandomClass.Next(1, 49)
    If RandomNumber2 = RandomNumber1 Then
        RandomNumber2 = RandomClass.Next(1, 49)
    End If

    ''#Displays second number generated
    txtSecond.Text = (RandomNumber2)



    ''####################################
    Dim RandomNumber3 As Integer
    RandomNumber3 = RandomClass.Next(1, 49)
    If RandomNumber3 = RandomNumber2 Or RandomNumber2 Then
        RandomNumber3 = RandomClass.Next(1, 49)
    End If

    ''#Displays third number generated
    txtThird.Text = (RandomNumber3)



    ''####################################
    Dim RandomNumber4 As Integer
    RandomNumber4 = RandomClass.Next(1, 49)
    If RandomNumber4 = RandomNumber3 Or RandomNumber2 Or RandomNumber1 Then
        RandomNumber4 = RandomClass.Next(1, 49)
    End If

    ''#Displays fourth number generated
    txtFourth.Text = (RandomNumber4)



    ''####################################
    Dim RandomNumber5 As Integer
    RandomNumber5 = RandomClass.Next(1, 49)
    If RandomNumber5 = RandomNumber4 Or RandomNumber3 Or RandomNumber2 Or RandomNumber1 Then
        RandomNumber5 = RandomClass.Next(1, 49)
    End If

    ''#Displays fifth number generated
    txtFifth.Text = (RandomNumber5)



    ''####################################
    Dim RandomNumber6 As Integer
    RandomNumber6 = RandomClass.Next(1, 49)
    If RandomNumber6 = RandomNumber5, RandomNumber4, RandomNumber3, RandomNumber2, RandomNumber1 Then
        RandomNumber6 = RandomClass.Next(1, 49)
    End If

    ''#Displays sixth number generated
    txtSixth.Text = (RandomNumber6)


End Sub

8 个答案:

答案 0 :(得分:5)

而不是“If”,使用“While” - 换句话说,继续生成随机数,直到找到新的。目前,如果您获得重复,然后在第二次尝试时获得重复,您将继续前进。

另外,虽然我不是VB专家,但我相信你需要完整地指定每个比较,所以不要这样:

If RandomNumber3 = RandomNumber2 Or RandomNumber2 Then
    RandomNumber3 = RandomClass.Next(1, 49)
End If

你需要:

While RandomNumber3 = RandomNumber1 Or RandomNumber3 = RandomNumber2 Then
    RandomNumber3 = RandomClass.Next(1, 49)
End While

这里有其他选择 - 例如生成数字1-49,将它们混洗,然后获取前6个结果......或者保持“选择直到有新结果”,但将结果保存在一组中。无论哪种方式,你都可以避免重复代码重复。

答案 1 :(得分:3)

您不仅需要一个随机数生成器,还需要一个与洗牌算法结合使用。

创建一个N项数组(我们将在示例中使用七个),每个项目包含与其位置相关的整数:

+---+---+---+---+---+---+---+
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
+---+---+---+---+---+---+---+
                            <pool(7)

并将池大小设置为7。

然后根据池大小生成随机数(即从1到7得到一个数字)。假设你的发电机返回3。

拉出位置3的值,然后用顶部值替换它,然后减小池大小:

+---+---+---+---+---+---+---+
| 1 | 2 | 7 | 4 | 5 | 6 | 7 | -> 3
+---+---+---+---+---+---+---+
                        <pool(6)

然后你继续这样做,直到你得到所需的数量。如果我们的乐透从7开始是5:

+---+---+---+---+---+---+---+
| 1 | 2 | 7 | 4 | 5 | 6 | 7 |
+---+---+---+---+---+---+---+
                            <pool(7)
rnd(7) returns 3
+---+---+---+---+---+---+---+
| 1 | 2 | 7 | 4 | 5 | 6 | 7 | -> 3
+---+---+---+---+---+---+---+
                        <pool(6)
rnd(6) returns 1
+---+---+---+---+---+---+---+
| 6 | 2 | 7 | 4 | 5 | 6 | 7 | -> 1
+---+---+---+---+---+---+---+
                    <pool(5)
rnd(5) returns 5
+---+---+---+---+---+---+---+
| 6 | 2 | 7 | 4 | 5 | 6 | 7 | -> 5
+---+---+---+---+---+---+---+
                <pool(4)
rnd(4) returns 2
+---+---+---+---+---+---+---+
| 6 | 4 | 7 | 4 | 5 | 6 | 7 | -> 2
+---+---+---+---+---+---+---+
            <pool(3)
rnd(3) returns 1
+---+---+---+---+---+---+---+
| 7 | 4 | 7 | 4 | 5 | 6 | 7 | -> 6
+---+---+---+---+---+---+---+
        <pool(2)

并且你有它,5比5的数字(3,1,5,2,6)被提取,没有重复的可能性和有效的O(n)方法来获得它们。任何依赖于获取随机数并检查它们是否已被使用的解决方案效率都会降低。

答案 2 :(得分:1)

如果你有VB2008,这是使用LINQ的另一个选项:

Dim rnd As New Random()

Dim randomNumbers = From n in Enumerable.Range(1, 49) _
                    Order By rnd.Next() _
                    Select n _
                    Take 6

'Do something with the numbers here

这是一种简单的方法。如果使用Random类不够随机,那么您可能必须选择另一种方法。

答案 3 :(得分:1)

您必须将我正在使用的文本框的名称更改为您正在使用的文本框。

    Dim rand As New Random
    Dim winnum As New List(Of Integer)
    Dim num, counter As Integer
    Dim result As String = ""

    Do
        num = rand.Next(1, 49)
        If winnum.Contains(num) Then
            Do
                num = rand.Next(1, 49)
            Loop Until winnum.Contains(num) = False
        End If
        winnum.Add(num)
        counter += 1
    Loop Until counter = 6

    'Extracting and displaying the numbers from the array

    For n As Integer = 0 To 5
        result = winnum(n) & " " & result
    Next

    'The textbox I'm using to display the result is result.text

    result.Text = result

答案 4 :(得分:1)

您也可以将代码用作上面建议的其他人。在下面的代码中,数字是随机生成的,并从数字池中删除,直到达到所需的数量。然后显示剩下的数字。然而,由于数字序列在某种程度上是可预测的,因此这不是生成彩票号码的好方法,但它们是独一无二的。这是代码:

    Dim rand As New Random, winnum As New List(Of Integer)
    Dim num As Integer, result As String = ""

    For n As Integer = 1 To 49
        winnum.Add(n)
    Next

    Do
        num = rand.Next(1, 49)

        If winnum.Contains(num) Then
            winnum.Remove(num)
        End If

    Loop Until winnum.Count = 7

    For n As Integer = 0 To 5
        result = winnum(n) & " " & result
    Next

    a.Text = result

答案 5 :(得分:0)

我会选择(在C#中)

public static IEnumerable<int> Lotto(int max)
    {
        var random = new Random((int)DateTime.Now.Ticks);
        var numbers = new List<int>(Enumerable.Range(1, max));
        while(numbers.Count > 0)
        {
            int index = random.Next(1, numbers.Count) - 1;
            yield return numbers[index];
            numbers.RemoveAt(index);
        }
    }

    static void Main(string[] args)
    {


        var lotto = Lotto(49).GetEnumerator();
        lotto.MoveNext();
        int r1 = lotto.Current;
        lotto.MoveNext();
        int r2 = lotto.Current;
        lotto.MoveNext();
        int r3 = lotto.Current; 

        Console.WriteLine("{0} {1} {2}", r1, r2, r3 );

    }

答案 6 :(得分:0)

您可以简单地遍历这些数字并检查每个数字的可能性,而不是选择随机数并检查重复项:

Dim count As Integer = 6 ' How many numbers to pick
Dim pos As Integer = 1 ' Lowest value to pick from
Dim items As Integer = 49 ' Number of items in the range

Dim rnd As New Random()
Dim result As New List(Of Integer)()

While count > 0
  If rnd.Next(items) < count Then
    result.Add(pos)
    count -= 1
  End If
  pos += 1
  items -= 1
End While

列表result现在包含六个不重复的数字,从1-49范围内随机挑选。作为额外奖励,列表中的数字已经排序。

答案 7 :(得分:0)

我认为改组也是最快的选择。但更容易阅读的是你的方法与集合的包含功能:

Dim numbers As New List(Of Int32)
For i As Int32 = 1 To 6
    Dim containsNextNumber As Boolean = False
    While Not containsNextNumber
        Dim rnd As New Random(Date.Now.Millisecond)
        Dim nextNumber As Int32 = rnd.Next(1, 50)
        If Not numbers.Contains(nextNumber) Then
            numbers.Add(nextNumber)
            containsNextNumber = True
        End If
    End While
Next
numbers.Sort() 'sort the numbers from low to high