канонический способ рандомизировать NSArray в Objective C

Существует ли канонический способ рандомизировать массив в Objective C?

38
задан Cœur 19 November 2019 в 07:13
поделиться

3 ответа

Моя служебная библиотека определяет эту категорию для NSMutableArray, чтобы сделать это:

@interface NSMutableArray (ArchUtils_Shuffle)
- (void)shuffle;
@end

// Chooses a random integer below n without bias.
// Computes m, a power of two slightly above n, and takes random() modulo m,
// then throws away the random number if it's between n and m.
// (More naive techniques, like taking random() modulo n, introduce a bias 
// towards smaller numbers in the range.)
static NSUInteger random_below(NSUInteger n) {
    NSUInteger m = 1;

    // Compute smallest power of two greater than n.
    // There's probably a faster solution than this loop, but bit-twiddling
    // isn't my specialty.
    do {
        m <<= 1;
    } while(m < n);

    NSUInteger ret;

    do {
        ret = random() % m;
    } while(ret >= n);

    return ret;
}

@implementation NSMutableArray (ArchUtils_Shuffle)

- (void)shuffle {
    // http://en.wikipedia.org/wiki/Knuth_shuffle

    for(NSUInteger i = [self count]; i > 1; i--) {
        NSUInteger j = random_below(i);
        [self exchangeObjectAtIndex:i-1 withObjectAtIndex:j];
    }
}

@end

Убедитесь, что вы запустили генератор случайных чисел (например, srandom (time (NULL))) ) когда-нибудь, прежде чем ты позвонишь; в противном случае результат будет не очень случайным.

59
ответ дан 27 November 2019 в 03:20
поделиться
if ([array count] > 1) {
    for (NSUInteger shuffleIndex = [array count] - 1; shuffleIndex > 0; shuffleIndex--)
        [array exchangeObjectAtIndex:shuffleIndex withObjectAtIndex:random() % (shuffleIndex + 1)];
}

Обязательно заполняйте функцию random () с помощью srandomdev () или srandom ().

7
ответ дан 27 November 2019 в 03:20
поделиться

В SDK нет встроенного, если это то, о чем вы просите.

Вы можете использовать любой алгоритм рандомизации или тасования, какой пожелаете. Разные алгоритмы имеют разные компромиссы с точки зрения случайности, эффективности и т. Д.

http://en.wikipedia.org/wiki/Shuffling#Shuffling_algorithms

Для алгоритмов, которые перемешивают «на месте», начинают с использования изменяемого массива

insertObject:atIndex:
removeObjectAtIndex:

Для алгоритмов, которые восстанавливают массив, передайте его оригиналу и создайте новый массив.

2
ответ дан 27 November 2019 в 03:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: