2012-01-07 11 views
1

numberを2回繰り返さないarc4random()をどのように記述しますか?arc4random()の番号に1回使用

たとえば、私はスイッチとボタンを使用しています。私は同じarc4random番号を再利用して生成したくありません。私がarc4randomの世代番号2,4,42,32,42 ... を持っていたら、私は再び42が出現したくありません。

どうすればこの問題を回避できますか?

switch (arc4random() % 50) 
     { 
      case 1: 
       text.text = @"You are silly boy"; 
       break; 
      case 2: 
       text.text = @"Well, you very very silly"]; 
       break; 
      case 3: 
       text.text = @"stop being silly"]; 
       break; 
      case 4: 
       [text.text = @"silly... silly"]; 
       break; 
      case 5: 
       text.text = @"what you silly boy"]; 
       break; 

      ... 
      case 0: 
       text.text = @"you silly"]; 
       break; 
     } 
+0

どのくらいの頻度で繰り返すことはできませんか? –

+1

Fisher-Yates:ここをクリックしてください:http://stackoverflow.com/questions/1858610/different-numbers-from-1-to-10/1858800#1858800 – paxdiablo

+0

arc4randomの結果は、約20億の数。しかし、数値は(擬似)ランダムなので、%50を使用すると2つの同一の数値が連続して得られます。一意性を保証するには、他の戦略を使用する必要があります。 –

答えて

-1

一つの方法は、次のようになります。

static int maxNumOfCases = 50; //This could be any number of cases that you need in your app. 

...... 

switch (arc4random() % (maxNumOfCases--)) { 
      case 1: 
       text.text = @"You are silly boy"; 
       break; 
      case 2: 
       text.text = @"Well, you very very silly"]; 
       break; 
      case 3: 
       text.text = @"stop being silly"]; 
       break; 
      case 4: 
       [text.text = @"silly... silly"]; 
       break; 
      case 5: 
       text.text = @"what you silly boy"]; 
       break; 
       ... 
      case 0: 
      text.text = @"you silly"]; 
      break; 
} 

このコードは、常に呼び出しのたびにユニークなケースに切り替わります。この方法は、以上の数字の小さい範囲にランの終わりに向かって付勢することに注意してください:コードが機能する方法は、1

アップデートにより、個々の呼び出しでarc4random()の範囲を減少させることによってです。したがって、これは真の非繰り返し乱数生成ではありません。しかし、それは懸念事項ではない場合、あなたのコードに含まれる簡単な1つのライナーです。

+1

この方法には非常に大きな偏りがあります。 'maxNumOfCases'が最初50で、' maxNumOfCases'が0に近づくと 'r =(arc4random()%(maxNumOfCases - ))' 'に対して、rは0に近づきます。 'maxNumOfCases'が50の場合、r = 1は7.0%時間とr = 50は時間の0.08%で発生し、他の値はこれらの値の間で増加します。この場合、** r = 1はr = 50よりも80倍以上高い**(パーセント値は近似値ですが近いですが、これらの値は経験的に500,000,000回の試行以上で計算されています)。 - CocoaFu 11分前 – zaph

+0

待ってください - これは機能的ではありません。それでも数字を繰り返すことができます。これはどう受け入れられたのですか? – IAmTheAg

6

arc4random()すなわち、各呼び出しは、他のすべての呼び出しとは独立であり、繰り返し発生はありません。しかし、それはまた、arc4random()を呼び出すだけでは(一般的に)50の一意の数字を生成しないことを意味します。

1つの方法は、必要な整数の配列を作成し、その配列を通り抜け、(arc4random()%50)を使ってランダムに(あなたの場合は)選択された別の配列にスワップします。彼らは配列から連続した値を使用し、最後に新しい配列を作成してランダム化します。

例:

int n = 50; 
int list[n]; 
for (int i = 0; i<n; i++) 
    list[i] = i; 

for (int i = n-1; i>=1; i--) { 
    int ran = arc4random() % (i+1); 
    int tmp = list[i]; 
    list[i] = list[ran]; 
    list[ran] = tmp; 
} 

for (int i = 0; i<n; i++) 
    NSLog(@"%d", list[i]); 

これは、フィッシャー・イェーツシャッフルの現代版である、コンピュータの使用のために設計されており、リチャードによって導入:リストの値は、繰り返しなしで0と49の間のランダムな数字になりますDurstenfeld。

注:modを使用して部分集合を作成すると、バイアスが作成されますが、50の場合、バイアスは無視されます。次のようにそれを行うの

+1

私はこのメソッドのランダム性分布については疑問です。 http://stackoverflow.com/questions/859253/why-does-this-simple-shuffle-algorithm-produce-biased-results-what-is-a-simple – tia

+0

Fisher-イェイツ? –

+0

Durstenfeldによって更新されたFisher-Yatesアルゴリズムの例を更新しました。 – zaph

関連する問題