我已经构建了一个基诺游戏,它从一个arraylist中选择了20个随机数,NumbersToPickFrom。我生成一个随机数,然后检查该数字当前是否可以从中挑选。如果是,我将它添加到我将用作彩票号码的数字arraylist,randomPicks,然后我从可用的数字中删除它。如果它不在列表中,那意味着它已被选中,我需要一个新号码。我用goto重新开始。我认为它工作正常,但似乎我一直在重复。我使用ArrayList.Remove函数错了吗?如果它被删除,我不应该在我的随机选择的最终列表中得到重复。如果有人能看到我错过的地方,那将会有所帮助。下面的代码只是我正在谈论的代码。
private void GeneratePicks()
{
for (int i = 1; i <= 20; )
{
Retry:
int rInt = GenerateRandomPick();
if (NumbersToPickFrom.Contains(rInt))
{
RandomPicks.Add(rInt);
NumbersToPickFrom.Remove(rInt);
i++;
//PickBox.Text += rInt + " ,";
RandomPicks.Sort();
}
else
{
goto Retry;
}
}
}
private int GenerateRandomPick()
{
int rInt = rand.Next(1,81);
return rInt;
}
private void initializeArray()
{
for (int i = 1; i <= 80; i++)
{
NumbersToPickFrom.Add(i);
}
}
答案 0 :(得分:3)
我运行了你的代码,并没有得到任何重复。
尽管如此,重复选择随机数并与缩小列表进行比较的方法并不是最好的方法。
请改为尝试:
RandomPicks =
Enumerable
.Range(1, 80)
.OrderBy(n => rand.Next())
.Take(20)
.OrderBy(n => n)
.ToList();
答案 1 :(得分:2)
我发现你的代码工作正常。
我添加了以下公共变量以使其工作(在我的机器上)
List<int> NumbersToPickFrom = new List<int>(); List<int> RandomPicks = new List<int>(); Random rand = new Random();
虽然在第二次运行中,我发现RandomPicks中的项目数量增加了一倍并且也有重复项,所以我更改了 initializeArray(),如下所示
private void initializeArray() { for (int i = 1; i <= 80; i++) { NumbersToPickFrom.Add(i); } RandomPicks.Clear(); // Added this to clear the existing values in the list. }
答案 2 :(得分:0)
如果你想这样做&#34;旧学校&#34;并实际观察发生的事情,将GeneratePicks()
方法更改为:
private void GeneratePicks()
{
RandomPicks = new List<int>();
initializeArray();
for (int i = 0; i < 20; ++i)
{
int randomIndex = rand.Next(1, 80 - i);
int randomPick = NumbersToPickFrom[randomIndex];
RandomPicks.Add(randomPick);
NumbersToPickFrom[randomIndex] = NumbersToPickFrom[80 - i - 1];
}
RandomPicks.Sort();
}
这将完成20次,并保证不重复。
答案 3 :(得分:0)
我无法在您的代码中看到任何错误,并通过运行代码测试您的代码100000次,并且没有任何重复。
然而,有更好的方法来获取随机数。一个简单的改进是从NumbersToPickFrom
列表中随机选择一个数字,而不是仅仅选择一个数字,然后你不需要内循环。
有一种更好的选择彩票号码的方法。您可以遍历数字并计算每个数字应该被选中的概率。挑选数字的概率为PicksLeft / NumbersLeft
,例如,数字1被挑选的概率为20 / 80
,然后概率根据选择的数字而变化:
private void GeneratePicks() {
int pick = 20;
for (int n = 1; pick > 0; n++) {
if (rand.Next(81 - n) < pick) {
RandomPicks.Add(n);
pick--;
}
}
}
由于这些数字是按顺序挑选的,因此您甚至不必对数字进行排序,而且您不需要NumbersToPickFrom
列表。