我有一个我为个人使用而构建的程序,它会从列表框中的一组选中项目中随机选择一部电影。我在此应用程序中编程的功能之一是能够生成“分层结果”。我的意思是分层结果是算法应首先随机选择三部电影,然后随机选择其中两部,最后随机选择这两部电影。
帮助说明我的意思:
电影列表:Shriek,Shriek 2,Shriek 3,Monsters Inc,Bambi,Bambi 2
第1层:尖叫3,Bambi,Bambi 2
第2层:尖叫3,Bambi
第3层:Bambi
我已使用以下代码成功完成此操作:
Private Sub btnPick_Click(sender As System.Object, e As System.EventArgs) Handles btnPick.Click
If boxMovies.CheckedItems.Count <> 0 Then
Dim rnd As New Random
If My.Settings.Tier = True Then
lbl1.Text = boxMovies.CheckedItems.Item(rnd.Next(boxMovies.CheckedItems.Count))
Randomize()
lbl2.Text = boxMovies.CheckedItems.Item(rnd.Next(boxMovies.CheckedItems.Count))
Randomize()
lbl3.Text = boxMovies.CheckedItems.Item(rnd.Next(boxMovies.CheckedItems.Count))
Randomize()
Dim stp2() As String = {lbl1.Text, lbl2.Text, lbl3.Text}
lbl4.Text = stp2(rnd.Next(stp2.Length))
Randomize()
lbl5.Text = stp2(rnd.Next(stp2.Length))
Randomize()
Dim stp3() As String = {lbl4.Text, lbl5.Text}
lbl6.Text = stp3(rnd.Next(stp3.Length))
Else
MessageBox.Show(boxMovies.CheckedItems.Item(rnd.Next(boxMovies.CheckedItems.Count)), "Movie Result", MessageBoxButtons.OK)
End If
Else
MessageBox.Show("Please pick at least one movie!", "No Movies Selected", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
End Sub
然而,我遇到的问题是电影可以在任何给定的层中随机生成两次。下面的图片应该有助于说明我的意思:
注意在第2阶段,“星球大战传奇”是如何生成两次的。这最终导致“星球大战传奇”成为第3层的确保结果。
我想知道是否有一种简单的方法(随意改进我的代码,我意识到它可能是低效的,我只是快速地将它们扔在一起)来解决这个问题。我希望每个层中的结果对于该层是唯一的。
答案 0 :(得分:1)
想象一下,你有一个带有N部电影的矢量V(或电影的索引)。
For i:=0 to 2 do
r := rand(N-i-1) // A random integer fro 0..N-i-1 inclusive
AddToResult( V[r] )
V[r] := V[N-i-1] // Override the selected element with the last one.
这个想法是从列表中选择一个随机元素,并将最后一个元素放在提取元素的位置。因此,新列表的长度为N-1,不包括提取的元素。这个新列表有不同的顺序,但因为我们选择了一个随机的顺序,所以我们不关心它。