我希望实现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
答案 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