Как сгенерировать неповторяющееся случайное число

Я пытаюсь рандомизировать числа в массиве. Я могу сделать это с помощью 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);

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

Другое решение использует криптографию:

  1. Создать случайный ключ
  2. Итерация между 0..n
  3. Зашифруйте каждое целое число и примените по модулю количество альтернатив, которые вы хотите использовать для вывода функции.

Есть некоторые дополнительные подробности, которые не имеют значения для вашего случая.

Другие вопросы по тегам