c# -在彩票程序中检查重复

本文关键字:检查 程序 彩票 | 更新日期: 2023-09-27 17:49:42

我必须写一个彩票程序,它产生1到40之间的6个数字,并检查是否重复。我对生成随机数没有问题,但我遇到的问题是检查它们的算法。除了下面的错误,代码似乎可以工作(我已经运行了很多次程序,从来没有得到任何数字作为重复(除了0,见下文)。

这些是bug。

  1. 我偶尔得到两个零作为最后两个数字。
  2. 一个零偶尔会出现在最后一个数字(但除了错误#1之外,在其他任何地方都不会出现)。

源代码如下:

using System;
using System.Linq;
namespace LottoV2Program
{
    class LottoV2
    {
         static void Main(string[] args)
        {
            //declare variables
             int[] lottoNumbers = new int[6];
            Random rand = new Random();
            int temp = 0;
            int count = 0;
            //fill array with lottery numbers
             for (int i = 0; i < lottoNumbers.Length; i++)
            {
                temp = rand.Next(1, 41);//generate random number
                 //check to see whether number has already been picked
                while (lottoNumbers.Contains(temp) == false)
                {
                    lottoNumbers[count] = temp;
                    count++;
                }
            }
            //display numbers on screen, one per line
            foreach (int i in lottoNumbers)
            {
                Console.WriteLine(i);
            }
            //pause
            Console.ReadLine();
        }//end mm

c# -在彩票程序中检查重复

你似乎有些逻辑颠倒了。:

 //check to see whether number has already been picked
 while (lottoNumbers.Contains(temp) == false)
 {
     lottoNumbers[count] = temp;
     count++;
 }

将循环,只要lottoNumbers不包含值temp

现在假设i = 3, lottoNumbers = { 20, 15, 0, 0, 0, 0 },新绘制的值temp20

在这种情况下,lottoNumbers.Contains(temp) == true不会进入while循环代码块,并且lottoNumbers不会增加任何值,但i会增加。因此,在6次迭代(绘制)之后,您将得到一个小于6的count,并且在lottoNumbers数组末尾至少有一个0的值。

你应该颠倒逻辑,这样你就可以一直画一个数字,直到你得到一个还没有画的数字:

temp = rand.Next(1, 41); // generate random number
// check to see whether number has already been picked
while (lottoNumbers.Contains(temp) == true)
    temp = rand.Next(1, 41); // already drawn, try again
// unique number drawn, add it.
lottoNumbers[i] = temp;

要以统计上负责任的方式做到这一点(即没有大的抽样误差),你应该通过生成所有数字,进行"费雪-叶茨洗牌"来随机化它们的顺序,并取前6个来防止能够绘制两次数字。

var rand = new Random();
var lottoNumbers = Enumerable
    .Range(1, 40)              // number 1 - 40
    .OrderBy(x => rand.Next()) // randomly shuffled
    .Take(6)                   // we only need 6
    .ToArray();                // as an array please.

与其检查数字是否已经被选中,为什么不做一个从1到40的每个数字的列表,然后随机选择一个,当完成后将其放在列表的末尾并减小随机最大值。

像这样的

class Program
{
    static void Main(string[] args)
    {
        const int retrieve = 6;
        const int maxNumber = 40;
        const int maxLine = 20;
        var numbers = Enumerable.Range(1, maxNumber).ToArray();
        var rnd = new Random();
        int[] result = new int[retrieve];
        int pos;
        for (int j = 0; j < maxLine; ++j)
        {
            int number = numbers.Length;
            for (int i = 0; i < retrieve; ++i)
            {
                pos = rnd.Next(0, number);
                result[i] = numbers[pos];
                number--;
                numbers[pos] = numbers[number];
                numbers[number] = result[i];
            }
            Console.WriteLine(string.Join(", ",result.OrderBy (x => x).Select(x => x.ToString("00")).ToArray()));
        }
        Console.ReadKey(false);
    }
}
  1. 生成随机数
  2. 如果号码已经生成,返回步骤1
  3. 将数字添加到当前位置并跳转到下一个

        for (int i = 0; i < lottoNumbers.Length; i++)
        {
            do
            {
                temp = rand.Next(1, 40);
            }
            while (lottoNumbers.Contains(temp));
            lottoNumbers[i] = temp;
        }
    

一个建议:你的问题不清楚,简单地说"这是我的代码,它有bug"是不够的…可以说是优雅的。StackOverflow非常欢迎你,但是请更好地了解这个社区。我邀请你来参观。

List代替正常的array尝试以下操作。你不会得到0或任何重复项。

using System;
using System.Collections.Generic;
public class Program
{
    public static void Main()
    {
        const int MAX_LOTTO_NUMBERS = 6;
        Random r = new Random();
        List<int> lotteryNumbers = new List<int>();
        while (lotteryNumbers.Count < MAX_LOTTO_NUMBERS)
        {
            int lottoNumber = r.Next(1, 41); // Generate random number from 1 - 40
            if (!lotteryNumbers.Contains(lottoNumber))
            {
                lotteryNumbers.Add(lottoNumber);
            }
        }
        Console.WriteLine(String.Join(", ", lotteryNumbers.ToArray()));
    }
}

结果:

9、6、25、36、16、29

查看下面的代码:https://dotnetfiddle.net/EF7Ndc

我不是c#爱好者。但逻辑很容易读懂。我认为你得到的是0因为你在运行lotttonnumbers的循环。长度= 6。如果有重复,你不做任何动作。

的例子:

  • i=0 temp =21 => lottonnumber [0]=21
  • i=1 temp =4 => lottonnumber [1]=4
  • i=2 temp =21 =>已经存在,所以跳过
  • i=3 temp =10 => lottonnumber[2]=21(注意数组索引没有更新)
  • i=4 temp =6 => lottonnumber [3]=6
  • i=5 temp =30 => lottonnumber [4]=30

循环在此结束。lottonnumber[5]未设置。因此,在打印时,空数组值可能打印为0