2017-10-23 11 views
2

私がしたいのは、それぞれ異なるファイルサイズのファイルを100個生成することです。行した場合:同じ番号を繰り返す/複製しないで乱数を生成する方法はありますか?

long rndsize = rnd.Next(1, 2000); 

は数43を生成した後、再びこの番号を生成しません。コンストラクタで

CreateFiles(100); 

と方法:それが存在する場合

for (int i = 0; i < numberoffiles; i++) 
{ 
    Random rnd = new Random(); 
    long rndsize = rnd.Next(1, 2000); 
    FileStream fs = new FileStream(@"c:\temp\files\huge_dummy_file" + i, FileMode.CreateNew); 
    fs.Seek(rndsize * 1024, SeekOrigin.Begin); 
    fs.WriteByte(0); 
    fs.Close(); 
} 
+1

[一覧をランダム](https://stackoverflow.com/questions/273313/randomize-a-listt)の可能性のある重複 – Lowkey

+1

このコードの背後にある考え方は何ですか?ランダムな位置[1、1024 * 2000-1]からファイルをゼロにしますか? –

答えて

1

その後、Randomのメイクだけで1つのインスタンスまず、および生成されたすべての数値を格納し、既存の回答にに追加するには、新たに生成された数

Random rnd = new Random(); 
List<long> generatedNumbers = new List<long>(); 
for (int i = 0; i < numberoffiles; i++) 
{ 
    long rndsize = rnd.Next(1, 2000); 
    if(generatedNumbers.Contains(rndSize)) 
    { 
     i--; 
     continue; 
    } 

    generatedNumbers.Add(rndSize); 
    FileStream fs = new FileStream(@"c:\temp\files\huge_dummy_file" + i, FileMode.CreateNew); 
    fs.Seek(rndsize * 1024, SeekOrigin.Begin); 
    fs.WriteByte(0); 
    fs.Close(); 
} 
+0

LookupがO(n)であることだけが必要なので、おそらく 'HashSet 'を使う方が良いでしょう。いくつかのシナリオでかなり遅い解決策になるかもしれません。 –

+0

@artavazd私は同意します.GUIDを使用することとは別の選択肢がありますか? –

+2

HashSetとDictionaryには検索のためのO(1)があり、SortedSetにはO(logn)があります。 –

3

は、番号チェックをHashSetのを追加し、あなたランド。それがrandと別の番号を行う場合。 あなたは100個のファイルしか生成していないので、最後の反復では約20個の数字を必要としますが、それほど長い時間はかかりません。

のでHashSet<int> existingNumbers = new HashSet<int>();

を追加し、代わりにlong rndsize = rnd.Next(1, 2000);

ドゥの:

int rndsize; 
do { 
    rndsize = rnd.Next(1, 2000); 
} while (existingNumbers.Contains(rndsize)); 
existingNumbers.Add(rndsize); 
+1

"keys" – pinkfloydx33

1

それは簡単です。生成中に各番号を書き留めてください。次に、新しい番号が生成された番号と等しくないことを確認します。

1

でファイルを作成する前に、それをチェックするために、リストを使用します。

同じ結果が得られるのは、ループの繰り返しごとにRandomクラスの新しいインスタンスを作成するためです。

このクラスでは、シードを使用して、擬似乱数を生成します。この擬似乱数は、最初に現在のティックカウントDateTime.Nowを使用して計算されます。この乱数は、新しい乱数を要求した後に変更され、次の乱数を準備します。

繰り返しごとに新しいインスタンスを生成する場合、インスタンスは同じシードを持つ可能性が高く、結果が同じになることがあります。

0

guidも使用できます。毎回異なる番号を生成します。これはasp.netの組み込み機能です。乱数を生成する関数を作ることよりもはるかに優れています。

1

重複を避けるには、その番号が生成されていることを確認する必要があります。高速検索のために、HashSetを使用することができます。これはかなりダミーの解決策です - 無限ループを避けるために、反復回数に制限があります。

using System; 
using System.Collections.Generic; 

public class Program 
{ 
    public static void Main() 
    { 
     var rnd = new Random(); 
     var rndGen = new UniqueRandomGenerator(rnd); 

     Console.WriteLine("Next random values from 1 to 5:"); 
     for (int i = 1; i <= 5; i++) { 
      var next = rndGen.GetNext(1, 6); 
      Console.WriteLine(next); 
     } 
    } 

    class UniqueRandomGenerator 
    { 
     readonly Random _rnd; 
     readonly HashSet<int> _generated; 
     readonly static int MAX_ITER_WHILE_GET_NEXT_RND = 100; 

     public UniqueRandomGenerator(Random rnd) 
     { 
      _rnd = rnd; 
      _generated = new HashSet<int>(); 

     } 

     public int GetNext(int lower, int upper) { 
      int next; 
      int i = 0; 
      do { 
       next = _rnd.Next(lower, upper); 
       i++; 
       if (i > MAX_ITER_WHILE_GET_NEXT_RND) 
        throw new InvalidOperationException("Exceed iter limit!"); 
      } 
      while (_generated.Contains(next)); 
      _generated.Add(next); 
      return next; 
     } 
    } 
} 
関連する問題