2013-01-15 3 views
2

알파벳 무작위로 된 모든 문자의 문자열을 원합니다. 바로 지금, 나는 26 문자의 배열을 변경하고, exchangeObjectAtIndex : 메서드를 사용하여 그들을 섞은 다음, 반환 한 문자열에 각 문자를 추가한다.효율적인 방법으로 임의의 알파벳 문자열을 생성 하시겠습니까?

이렇게하는 것이 더 좋은 방법입니다. 여기 내 코드 :

- (NSString *)shuffledAlphabet { 
    NSMutableArray * shuffledAlphabet = [NSMutableArray arrayWithArray:@[@"A",@"B",@"C",@"D",@"E",@"F",@"G",@"H",@"I",@"J",@"K",@"L",@"M",@"N",@"O",@"P",@"Q",@"R",@"S",@"T",@"U",@"V",@"W",@"X",@"Y",@"Z"]]; 

    for (NSUInteger i = 0; i < [shuffledAlphabet count]; ++i) { 
     // Select a random element between i and end of array to swap with. 
     int nElements = [shuffledAlphabet count] - i; 
     int n = (random() % nElements) + i; 
     [shuffledAlphabet exchangeObjectAtIndex:i withObjectAtIndex:n]; 
    } 

    NSString *string = [[NSString alloc] init]; 
    for (NSString *letter in shuffledAlphabet) { 
     string = [NSString stringWithFormat:@"%@%@",string,letter]; 
    } 

    return string; 
} 
+0

임의의 문자 스트링을 원하십니까? 아니면 알파벳 글자의 임의 치환을 원하십니까 (즉, "반복없는 임의의 시퀀스")? - 질문의 제목은 첫 번째를 제안하고 코드는 후자를 제안합니다. –

+0

글자의 반복이나 단순히 섞은 알파벳에 만족합니다. 셔플 된 알파벳이 내가 그 방법을 쓸 때 마음에 떠오른 첫 번째 것이 었습니다. – Joshua

+1

자, 원하는 것을 결정하십시오. 그 중 두 가지는 정말 다릅니다. – erkanyildiz

답변

7

여기에 사용 사례에 맞게 효율적 Fisher-Yates shuffle을,이다 :

- (NSString *)shuffledAlphabet { 
    NSString *alphabet = @"ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 

    // Get the characters into a C array for efficient shuffling 
    NSUInteger numberOfCharacters = [alphabet length]; 
    unichar *characters = calloc(numberOfCharacters, sizeof(unichar)); 
    [alphabet getCharacters:characters range:NSMakeRange(0, numberOfCharacters)]; 

    // Perform a Fisher-Yates shuffle 
    for (NSUInteger i = 0; i < numberOfCharacters; ++i) { 
     NSUInteger j = (arc4random_uniform(numberOfCharacters - i) + i); 
     unichar c = characters[i]; 
     characters[i] = characters[j]; 
     characters[j] = c; 
    } 

    // Turn the result back into a string 
    NSString *result = [NSString stringWithCharacters:characters length:numberOfCharacters]; 
    free(characters); 
    return result; 
} 
1

Generating random numbers in Objective-C이 정보가 도움이 되셨습니까? * * 나누기 (26)에 의해 임의의 숫자 를 생성하고 알림을 * 인덱스 배열를 처음 셔플 대신 문자열을 구축하는 동안 당신은 (나머지) 알파벳에서 임의 요소를 선택할 수

+1

그의 질문을 더 잘 읽습니다. – erkanyildiz

0

[알림]을 가지고 :

NSMutableArray *alphabet = [NSMutableArray arrayWithObjects:@"A",@"B",@"C",@"D",@"E",@"F",@"G",@"H",@"I",@"J",@"K",@"L",@"M",@"N",@"O",@"P",@"Q",@"R",@"S",@"T",@"U",@"V",@"W",@"X",@"Y",@"Z", nil]; 
NSMutableString *result = [NSMutableString string]; 
NSUInteger numberOfLetters = alphabet.count; 
for (NSUInteger i = 0; i < numberOfLetters; i++) { 
    int n = arc4random() % alphabet.count; 
    [result appendString:[alphabet objectAtIndex:n]]; 
    [alphabet removeObjectAtIndex:n]; 
} 
NSLog(@"%@", result); 

이렇게하면 코드가 조금 짧아집니다. 문자가 추가 될 때마다 NSMutableString을 사용하면 NSString을 새로 만드는 것보다 더 효율적입니다.

+1

배열을 셔플하기위한 정렬 알고리즘을 사용하는 것은 좋은 생각이 아닙니다. 먼저 다른 조합은 동일한 확률을 갖지 않습니다. 둘째로, 효율적인 셔플 알고리즘은'O (n)'의 복잡성을 가지는 반면, 점근 적 복잡성은'O (log (n) * n)'이다. [이 질문에 대한 답변]을 보셔야합니다 (http://stackoverflow.com/questions/790083/does-qsort-demand-consistent-comparisons-or-can-i-use-it-for-shuffling). . –

+1

해당 링크를 제공해 주셔서 감사합니다. 대체 버전을 삭제했습니다. – omz

2

이 올바르게 단행 알파벳 세대를 수행 할 수있는 더 효율적인 방법입니다.

- (NSString *)shuffledAlphabet 
{ 
    const NSUInteger length = 'Z' - 'A' + 1; 
    unichar alphabet[length]; 
    alphabet[0] = 'A'; 

    for (NSUInteger i = 1; i < length; i++) 
    { 
     NSUInteger j = arc4random_uniform((uint32_t)i + 1); 
     alphabet[i] = alphabet[j]; 
     alphabet[j] = 'A' + i; 
    } 
    return [NSString stringWithCharacters:alphabet length:length]; 
} 

그것은 피셔 예이츠 셔플의 "내부 아웃"버전을 사용 arc4random_uniform하여 의사 난수를 생성하여 모듈라 바이어스를 피한다. 또한 모든 순열은 임시 버퍼에서 수행되므로 단일 할당이 필요합니다.

+1

이 답변에는 링크가 있어야합니다. 나는 그들이 왜 표시되지 않는지 이해하지 못한다. –

관련 문제