2012-01-07 2 views
1

Как вы код arc4random(), который не повторяет число дважды?Использовать один раз на arc4random() number

Например. Я использую переключатель и кнопку. Я не хочу повторять повторное использование того же самого числа 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, вероятно, не повторяется примерно для 2 миллиардов номеров , Но, поскольку числа являются (псевдо) случайными, когда вы используете% 50, вы можете получить два одинаковых числа подряд. Вы должны использовать другую стратегию, чтобы обеспечить уникальность. –

ответ

-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; 
} 

Этот код всегда переключается на уникальный случай на каждом вызове. То, как код работает, за счет уменьшения диапазона arc4random() при каждом вызове на 1.

Update: Держите внимание, что этот метод смещает больше к концу пробега в меньшем диапазоне чисел. Таким образом, это не истинное не повторяющееся генерирование случайных чисел. Но если это не проблема, ее легкий лайнер для включения в ваш код.

+1

Существует очень существенный уклон с этим методом. Для 'r = (arc4random()% (maxNumOfCases -))' где 'maxNumOfCases' изначально 50, поскольку« maxNumOfCases »приближается к 0, r приближается 0. Для' maxNumOfCases' из 50 r = 1 произойдет 7.0% время и r = 50 будут происходить 0,08% времени, а другие значения будут разбросаны между этими значениями. Для этого случая ** r = 1 более чем в 80 раз чаще, чем r = 50. ** (Процентные значения являются приблизительными, но близкими, эти значения были рассчитаны эмпирически более чем 500 000 000 попыток). - CocoaFu 11 мин назад – zaph

+0

Подождите секунду - это даже не функционально. Он все еще может повторять цифры. Как это было принято. – IAmTheAg

6

arc4random() не повторяющаяся генератор, то есть каждый вызов не зависит от всех других вызова. Но это также означает, что просто вызывать arc4random() не будет (вообще) производить 50 уникальных номеров.

Один из способов - создать массив целых чисел, который вы хотите, а затем пройти через массив и поменять каждый на другой, выбранный случайным образом (в вашем случае) с помощью (arc4random()% 50). Они просто используют последовательные значения из массива и когда в конце создают новый массив и рандомизируют его.

Пример: Значения в списке будут случайные числа в диапазоне от 0 до 49 лет, без повторов:

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]); 

Это современная версия перетасовки Fisher-Yates, предназначена для использования компьютера и представил Ричард Durstenfeld.

Примечание: использование мода для создания подмножества создает смещение, но в случае 50 смещение пренебрежимо мало.

+1

Я сомневаюсь в распределении случайности этого метода. Взгляните на http://stackoverflow.com/questions/859253/why-does-this-simple-shuffle-algorithm-produce-biased-results-what-is-a-simple – tia

+0

Почему бы не сделать это правильно с помощью Fisher- Йейтс? –

+0

Я обновил пример алгоритму Fisher-Yates, обновленный Durstenfeld. – zaph