Как сгенерировать неповторяющееся случайное число
Я пытаюсь рандомизировать числа в массиве. Я могу сделать это с помощью arc4random() % [indexes count]
Моя проблема - если массив состоит из 20 элементов, каждый раз, когда массив перемешивается, в пакете из 5 должно появляться другое число. Пример:
первая случайная последовательность: 1,4,2,5,6.
второй случайный порядок: 7,12,9,15,3
-(IBAction)randomNumbers:(UIButton *)sender
{
int length = 10; // int length = [yourArray count];
NSMutableArray *indexes = [[NSMutableArray alloc] initWithCapacity:length];
for (int i=0; i<5; i++)
[indexes addObject:[NSNumber numberWithInt:i]];
NSMutableArray *shuffle = [[NSMutableArray alloc] initWithCapacity:length];
while ([indexes count])
{
int index = arc4random() % [indexes count];
[shuffle addObject:[indexes objectAtIndex:index]];
[indexes removeObjectAtIndex:index];
}
// for (int i=0; i<[shuffle count]; i++)
NSLog(@"%@", [shuffle description]);
}
4 ответа
Согласно вашему требованию.... пожалуйста, проверьте этот код
Сделать это свойство
@synthesize alreadyGeneratedNumbers;
Добавьте эти методы в свой.m
-(int)generateRandomNumber{
int TOTAL_NUMBER=20;
int low_bound = 0;
int high_bound = TOTAL_NUMBER;
int width = high_bound - low_bound;
int randomNumber = low_bound + arc4random() % width;
return randomNumber;
}
-(IBAction)randomNumbers:(UIButton *)sender
{
NSMutableArray *shuffle = [[NSMutableArray alloc] initWithCapacity:5];
BOOL contains=YES;
while ([shuffle count]<5) {
NSNumber *generatedNumber=[NSNumber numberWithInt:[self generateRandomNumber]];
//NSLog(@"->%@",generatedNumber);
if (![alreadyGeneratedNumbers containsObject:generatedNumber]) {
[shuffle addObject:generatedNumber];
contains=NO;
[alreadyGeneratedNumbers addObject:generatedNumber];
}
}
NSLog(@"shuffle %@",shuffle);
NSLog(@"Next Batch");
if ([alreadyGeneratedNumbers count] >= TOTAL_NUMBER) {
NSLog(@"\nGame over, Want to play once again?");//or similar kind of thing.
[alreadyGeneratedNumbers removeAllObjects];
}
}
Тем не менее я чувствую, что вам нужны некоторые изменения, такие как
это даст вам правильное значение, но что, если пользователь нажал 5-й раз?
из 20 чисел, которые вы уже выбрали, 4 набора по 5 чисел, в шестой раз он будет в цикле поиска следующего набора чисел и станет бесконечным.
Таким образом, вы можете следить за случайным движением и, как только он достигнет предела, т.е. 20/5=4, отключить случайную кнопку.
Объявите массив, который содержит уже сгенерированный номер в файле расширения или заголовка
@property (strong, nonatomic)NSMutableArray *existingNums;
@property (assign, nonatomic)NSInteger maxLimit;
@property (assign, nonatomic)NSInteger minLimit;
Затем внедрить данный код в файл реализации
@synthesize existingNums;
@synthesize maxLimit;
@synthesize minLimit;
- (NSInteger)randomNumber {
if(!existingNums)
existingNums = [NSMutableArray array];
while (YES) {
NSNumber *randonNum = [NSNumber numberWithInteger:minLimit+arc4random()%maxLimit];
if([existingNums containsObject:randonNum]) {
if([existingNums count] == (maxLimit - minLimit))
return -1; // All possible numbers generated in the given range
continue;
}
[existingNums addObject:randonNum];
return [randonNum integerValue];
}
return -1; // return error
}
Надеюсь, что это поможет вам:)
Этот работает для меня:
NSMutableArray *numbers = [NSMutableArray new];
BOOL addElement = YES;
int limit = 100; // Range from 0 to 36
int numElem = 10; // Number of elements
do
{
int ranNum = (arc4random() % limit) +1;
if ([numbers count] < numElem) {
for (NSNumber *oneNumber in numbers) {
addElement =([oneNumber intValue] != ranNum) ? YES:NO;
if (!addElement) break;
}
if (addElement) [numbers addObject:[NSNumber numberWithInt:ranNum]];
} else {
break;
}
} while (1);
NSLog(@"%@",numbers);
Проблема со всеми этими ответами состоит в том, что вам нужно просмотреть ваши предыдущие сгенерированные случайные числа, и это занимает дополнительное время, если вам нужно большое количество случайных целых чисел.
Другое решение использует криптографию:
- Создать случайный ключ
- Итерация между 0..n
- Зашифруйте каждое целое число и примените по модулю количество альтернатив, которые вы хотите использовать для вывода функции.
Есть некоторые дополнительные подробности, которые не имеют значения для вашего случая.