随机化一个数组

时间:2012-11-11 13:39:31

标签: arrays vb.net

我希望实现Dr.D.E.Knuth的Subtractive RANDOM数生成算法。我希望实现一个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

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

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

现在主要的任务是使用btnArray()功能对Random()进行随机播放..但我没有做到这一点。我设法得到一些代码来改组数组,如下所示:

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(输出(n))。 但它并没有像我想要的那样工作,ABOVE代码只是为了表明我想要的方式2洗牌按钮。 有没有更简单的方法来创建一个按钮数组并使用RANDOM()随机化它们并添加到表单。 我的朋友们说你是如此愚蠢,以至于你从去年20 - 25日开始研究这个话题

3 个答案:

答案 0 :(得分:2)

有一些“shuffle”算法(例如搜索Fisher-Yates)并且它们通常不难实现。 EASIEST(imho)方式,使用LINQ:

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

也许问题不明确:你想要改变按钮的位置,还是想要改组数组的内容(按钮)?

答案 1 :(得分:0)

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

答案 2 :(得分: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