检查数字是否唯一,然后将其添加到数组中.帮助查找错误
本文关键字:数组 帮助 错误 查找 添加 是否 数字 唯一 然后 检查 | 更新日期: 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();
}
}
}
}