-2

以下の要件を満たす C# アプリケーションの一意の番号を生成する必要があります。

  1. 6桁。

  2. 毎日生成される約1000個の数字

    byte[] buffer = Guid.NewGuid().ToByteArray();
    return string.Concat(((int)type).ToString(), 
     BitConverter.ToInt64(buffer, 0).ToString().Substring(1,    
                    6-((int)type).ToString().Length));
    

現在、私はこのアルゴリズムを使用していますが、重複が発生するため、上記の要件に適合する別のアルゴリズムが必要です。

4

1 に答える 1

0

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の数値を返すことも、呼び出されるたびに次の数値を順番に返すメソッドを作成することもできます。

于 2013-03-08T21:33:09.943 に答える