2

我希望实现 Dr.DEKnuth 的减法随机数生成算法。我希望实现一个 ATM 面板,当用户登录时,按钮将被打乱。每个按钮都会改变它的位置。

这是我的代码:

Public Sub addbutton()
        Dim n As Integer = 0

        For i As Integer = 0 To 10
            ' Initialize one variable
            btnArray(i) = New System.Windows.Forms.Button
        Next i

        While (n < 10)
            With (btnArray(n))
                .Tag = n + 1 ' Tag of button
                .Width = 40 ' Width of button
                .Height = 40
                FlowLayoutPanel1.Controls.Add(btnArray(n))
                .Text = Chr(n + 48)
                AddHandler .Click, AddressOf Me.ClickButton
                n += 1
            End With
        End While
    End Sub

然后,为了向按钮文本发送信息,我使用了:

 Dim btn As Button = sender
        TextBox1.Text += btn.Text

现在的主要任务是改组btnArray()withRandom()函数。但我没有做到这一点。我设法获得了一些用于改组数组的代码,如下所示:

Imports System.Security.Cryptography

Public Class ArrayUtilities
    Private Random As RNGCryptoServiceProvider = New RNGCryptoServiceProvider
    Private Bytes(4) As Byte

    Public Function ShuffleArray(ByVal argArr As Array) As Array
        Dim FirstArray As New ArrayList(argArr)
        Dim SecoundArray As Array = Array.CreateInstance(GetType(Object), FirstArray.Count)
        Dim intIndex As Integer
        For i As Integer = 0 To FirstArray.Count - 1
            intIndex = RandomNumber(FirstArray.Count)
            SecoundArray(i) = FirstArray(intIndex)
            FirstArray.RemoveAt(intIndex)
        Next
        FirstArray = Nothing
        Return SecoundArray
    End Function

    Private Function RandomNumber(ByVal argMax As Integer) As Integer
        If argMax <= 0 Then Throw New Exception
        Random.GetBytes(Bytes)
        Dim intValue As Integer = (BitConverter.ToInt32(Bytes, 0)) Mod argMax
        If intValue < 0 Then intValue = -intValue
        Return intValue
    End Function
End Class

Module Module1
    Sub Main()
        Dim AU As ArrayUtilities

        AU = New ArrayUtilities

        Dim GivenArray As Integer() = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
        Dim NewArray As Array = AU.ShuffleArray(GivenArray)
        Dim i As Integer
        Dim stb As New System.Text.StringBuilder
        stb.Append("GivenArray = {0,1,2,3,4,5,6,7,8,9}")
        stb.Append(vbCrLf)
        stb.Append("NewArray = {")
        For i = 0 To NewArray.Length - 2
            stb.Append(NewArray(i).ToString)
            stb.Append(", ")
        Next
        stb.Append(NewArray(NewArray.Length - 1).ToString)
        stb.Append("}")
        Console.Write(stb.ToString)
        Console.Read()
    End Sub
End Module

然而,当我们调试这段代码时,我们得到了数组的 RANDOMNESS。同样,我希望表单上的按钮具有随机性。

谢谢你,先生。先生,我尝试了您建议的代码。我错过了增量字符“n”。可调试代码是 flowlayoutpannel.controls.add(out(n))。但它没有像我想要的那样工作,上面的代码只是为了展示我想要的方式 2 随机播放按钮。有没有更简单的方法来创建一个按钮数组并使用 RANDOM() 将它们随机化并添加到表单中。我的朋友说你太愚蠢了,你从过去的 20 到 25 天都在研究这个话题

4

3 回答 3

2

有相当多的“洗牌”算法(例如搜索 Fisher-Yates),它们通常不难实现。最简单(恕我直言)的方式是使用 LINQ:

Dim r As New Random
Dim out = (From b In btnArray Order By r.Next Select b).ToArray

也许这个问题并不清楚:你想洗牌按钮的位置还是你想洗牌数组的内容(按钮)?

于 2012-11-12T08:12:19.640 回答
0

要在面板中随机设置按钮的位置,而不是在循环中使用从 0 到 9 的 n,可以使用从 0 到 9 的随机值。确保不要使用相同的值两次。

于 2012-11-11T15:46:07.783 回答
0

您不需要为此使用加密安全的随机数生成器,也不需要单独的类。

Private Shared rng As New Random()

Private Shared Function ShuffleArray(Of T)(arr() As T) As T()
    Dim left = Enumerable.Range(0, arr.Length).ToList()
    Dim result(arr.Length - 1) As T

    For i = 0 To arr.Length - 1
        Dim nextIndex = rng.Next(left.Count)
        result(i) = arr(left(nextIndex))
        left.RemoveAt(nextIndex)
    Next

    Return result
End Function
于 2012-11-13T05:06:06.337 回答