6桁の数字を1,000個しか生成していない場合は、非常に簡単です。
int NumberToGenerate = 1000;
Random rnd = new Random();
HashSet uniqueNumbers = new HashSet<int>();
while (uniqueNumbers.Count < NumberToGenerate)
{
int next = Random.Next(100000, 1000000);
uniqueNumbers.Add(next);
}
ループはほぼ確実にいくつかの重複を生成しますがHashSet
、それらを拒否します。
これを行う別の方法は、100,000から999,999までのすべての番号のリストを作成することです。次に、番号が必要な場合は、リストからランダムにアイテムを削除します。
private List<int> allNumbers = new List<int>();
// in the constructor
for (var i = 100000; i < 1000000; ++i)
{
allNumbers.Add(i);
}
private Random rnd = new Random();
public int GetNumber()
{
var index = rnd.Next();
var rslt = allNumbers[index];
allNumbers.RemoveAt(index);
return rslt;
}
への呼び出しRemoveAt
はちょっと高価です。あなたは物事を少しスピードアップすることができます:
// move the last number in the list to fill the hole
allNumbers[index] = allNumbers[allNumbers.Count-1];
// remove the last item
allNumbers.RemoveAt(allNumbers.Count-1);
これにより、削除時に移動されるメモリの量が最小限に抑えられます。
または、すべての番号のリストを作成し、それらをシャッフルしてから、前面から返すことができます。
// assume you've created the list of numbers, as above
// Shuffle them
for (int i = 0; i < allNumbers.Count; ++i)
{
int j = rnd.Next(i, allNumbers.Count);
int temp = allNumbers[i];
allNumbers[i] = allNumbers[j];
allNumbers[j] = temp;
}
これで、上位1,000の数値を返すことも、呼び出されるたびに次の数値を順番に返すメソッドを作成することもできます。