检查数字是否唯一,然后将其添加到数组中.帮助查找错误

本文关键字:数组 帮助 错误 查找 添加 是否 数字 唯一 然后 检查 | 更新日期: 2023-09-27 18:34:16

我正在做一个使用 Random() 类的应用程序,填充数组中数字的方法有一个错误。它仍然在数组中添加相同的值。它应该检查随机生成的值是否已经在数组中,如果它不在那里添加它。否则,它应该离开循环并生成另一个整数。

法典:

    /*
     * Method to fill in the array with numbers
     */
    public void FillArrayWithRandomNumbers()
    {
        bool unique = false;
        for (int i = 0; i < NrOfWantedNumbers; i++)
        {
            _randomNumber = rndm.Next(1, MaxValue) + 1;
            while (unique == false)
            {
                foreach (var item in storeLottoNum)
                {
                    if (item == _randomNumber)
                        unique = false;
                    else
                    {
                        unique = true;
                    }
                }
            }
            if (unique)
                storeLottoNum[storeNextIndex] = _randomNumber;
                ++storeNextIndex;
                unique = false;
        }  
    }

检查数字是否唯一,然后将其添加到数组中.帮助查找错误

如果您添加了大括号,您的代码可能会起作用。您在 if 语句下缩进了代码,但没有添加任何大括号。这不是Python。

if (unique == true) // By the way, can be shortened to if (unique)
{ // <-- You were missing this
    storeLottoNum[storeNextIndex] = _randomNumber;
    ++storeNextIndex;
    unique = false;
} // <-- You were missing this too

不过,一种更简单的方法:

unique = !storeLottoNum.Contains(item)

这一行可以完全消除您的while循环和其中的所有内容。这将自动设置您的unique变量。

假设:

  • storeLottoNum 是 int[] 类型;
  • storeLottoNum 的大小 = NrOfWantedNumbers
  • 存储下一个索引初始化为 0

编辑:在代码中添加了注释

然后尝试:

  /*
 * Method to fill in the array with numbers
 */
public void FillArrayWithRandomNumbers()
{
     for (int i = 0; i < NrOfWantedNumbers; i++)  // for each number you want
    {
        do
        {
            unique = true;                                     // Assume new value is unique
            _randomNumber = rndm.Next(1, MaxValue) + 1;        // get the random number
            for (int item = 0; item < storeNextIndex; item++)  // Check each element with a value in your array
            {
                if (storeLottoNum[item] == _randomNumber)      // if the value is the same
                {
                    unique = false;       // It is not unique
                    break;                // break the loop, we don't care about the other values
                }
            }
        } while (unique == false);        // if it was not unique, try again
        storeLottoNum[storeNextIndex++] = _randomNumber;   // with unique value, save in the array and increment the 'storeNextIndex'
    } 
}

另一种选择是使用字典<>或HashSet<>的默认特征。

默认情况下,这些类型的集合不允许重复键。在字典中遇到一个异常时,会引发异常。当在哈希集中遇到一个时,重复项将被简单地丢弃。通过将 KeyValuePair 添加到字典集合类型的过程包装在 try/catch 块中,并在抛出异常时简单地吸收异常,您可以非常轻松地构建随机唯一值的列表。请参阅以下示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LottoSample
{
    class Program
    {
        static void Main(string[] args)
        {
            Random random = new Random();
            // Dictionary to store list of random numbers
            Dictionary<int, bool> _lottoNumbers = new Dictionary<int, bool>();
            // Total amount of numbers
            int count = 50;
            while (count > 0)
            {
                // Attempt to add a new random number into the Dictionary of lotto numbers and reduce count by 1
                try
                {
                    _lottoNumbers.Add(random.Next(1, 100), true);
                    count--;
                }
                catch
                {
                    // Dictionaries and HashSets don't allow duplicate keys by default.
                    // When an attempt to add a duplicate to a dictionary is encountered, an exception is thrown.
                    // We simply ignore it. Because we still want X number of random numbers,
                    // we don't bother reducing the counter unless it succeeds.
                }
            }
            // Print the result
            foreach (var num in _lottoNumbers)
                Console.WriteLine(num);
            // Prevent the console window from closing
            Console.ReadLine();
        }
    }
}

这是使用HashSet的解决方案<>。这完全消除了必须使用 Try/Catch 块的需要。(因为它通常被认为是专业环境中的不良做法):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LottoSample
{
    class Program
    {
        static void Main(string[] args)
        {
            Random _random = new Random();
            // HashSet to store list of random numbers
            // When an attempt to add a duplicate is
            // encountered. They simply ignore the attempt silently.
            HashSet<int> _lottoNumbers = new HashSet<int>();
            // Total amount of numbers
            int _count = 50;
            int _randomNumber = -1;
            while (_count > 0)
            {
                // Get a random number
                _randomNumber = _random.Next(1, 100);
                _lottoNumbers.Add(_randomNumber); 
                _count--;
            }
            // Print the result
            foreach (var num in _lottoNumbers)
                Console.WriteLine(num);
            // Prevent the console window from closing
            Console.ReadLine();        
        }
    }
}

我知道,我有点得意忘形。这是一个更面向对象的解决方案:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LottoSample
{
    class Program
    {
        const int QTY = 10;
        static void Main(string[] args)
        {
            // A lotto numbers object which is initialized with the total amount of random numbers.
            var _lottoNumbers = new LottoNumbers(QTY);
            Random _random = new Random();
            int _count = QTY;       // Iterator
            int _randomNumber = -1; // Stores the random number
            // As long as there is still slots available, add a new random number
            while (_count > 0)
            { 
                // Get a random number
                _randomNumber = _random.Next(1, 100);
                // Attempt to add the number to the lotto numbers
                if (_lottoNumbers.Add(_randomNumber) == true)
                {
                    // It was successful, reduce the count by 1
                    _count--;
                }
                // Otherwise, try again until a unique value is found.
            }
            // Display the result
            Console.WriteLine(_lottoNumbers.ToString());
            Console.ReadLine();
        }
        public class LottoNumbers
        {
            private HashSet<int> _numbers;
            private int _total;
            public LottoNumbers()
            {
                this._numbers = new HashSet<int>();
            }
            public LottoNumbers(int total)
                : this()
            {
                _total = total;
            }
            public bool Add(int number)
            {
                // Check to see if the count of numbers is greater than the limit
                // Throw an exception if so.
                if (this.Count() >= _total)
                    throw new ArgumentOutOfRangeException();
                // Check to see if the number already exists and return true if so.
                if (this._numbers.Contains(number))
                    return false;
                // Add the number otherwise and return true.
                this._numbers.Add(number);
                return true;
            }
            // Overriden ToString() that displays a formatted list of numbers 
            public override string ToString()
            {
                var sb = new StringBuilder();
                foreach (var n in _numbers)
                {
                    sb.AppendFormat("{0}", n);
                    // If the number isn't the last in the list, append a comma
                    if (n != _numbers.Last())
                    {
                        sb.Append(",");
                    }
                }
                return sb.ToString();
            }
            // Get the count of numbers
            private int Count()
            {
                return this._numbers.Count();
            }
        }
    }
}