2016-09-07 3 views
0

문제에 대한 최선의 방법을 찾으려고합니다. 나는 즉시 발생하고있어 본질적으로 임의의 영숫자 문자열이 있습니다NSString의 대문자 임의 문자

NSString *string = @"e04325ca24cf20ac6bd6ebf73c376b20ac57192dad83b22602264e92dac076611b51142ae12d2d92022eb2c77f"; 

당신이 특수 문자, 단지 숫자와 문자가없고, 모든 문자는 소문자로 볼 수 있습니다. 대문자로이 문자열의 모든 문자를 변경하는 것은 간단하다

[string capitalizedString]; 

어려운 부분은 내가,이 문자열에서 임의의 문자를 대문자로 그들 모두하지 원하는 것입니다. 이 무작위이기 때문에, 이것은 또 다른에 출력 할 수

E04325cA24CF20ac6bD6eBF73C376b20Ac57192DAD83b22602264e92daC076611b51142AE12D2D92022Eb2C77F 

: 예를 들어,이 하나의 실행에 출력을 할 수

이 경우
e04325ca24cf20aC6bd6eBF73C376B20Ac57192DAd83b22602264E92dAC076611B51142AE12D2d92022EB2c77f 

는이 쉬워집니다,의 내가이 있다고 가정 해 봅시다

int charsToUppercase = 12;//hardcoded value for how many characters to uppercase here 
int totalChars = 90;//total string length 

이 경우에는이 문자열에서 90 개의 12 개의 임의의 문자가 대문자로 표시됩니다.

NSUInteger len = [string length]; 
unichar buffer[len+1]; 

[string getCharacters:buffer range:NSMakeRange(0, len)]; 

NSLog(@"loop through each char"); 
for(int i = 0; i < len; i++) { 
    NSLog(@"%C", buffer[i]); 
} 

는 여전히 대문자로이 루프에서 무작위로 문자를 선택 붙어, 그래서 모두 대문자로되어 있지 : 내가 지금까지 알아 냈어요 것은 내가 비교적 쉽게 문자열의 각 문자를 통해 루프를 할 수 있다는 것입니다. for 루프의 조건이 충분히 빠르다고 가정 할 때 트릭을 잘 수행 할 수 있다고 생각합니다.

+0

첫 번째 : 무작위에 대한 질문의 임의 색인 생성, 반복 없음 등) (문자가 많으면 NSRange range = NSMakeRange (randomIndex, 1); [mutableString replaceCharactersInRange : range withString : [[mutableString substringFromRange : range] 대문자]];)와 같은 문자를 대체합니다. 대문자로 바꾸는 숫자는 수정으로 간주됩니까? – Larme

+0

재미있는 @Larme, 재미있는 아이디어입니다.이 퍼즐의 맥락에서 그것이 숫자 일 경우 계산되지 않는다고 가정 해 봅시다. – Tiago

+0

만약 있다면 –

답변

1

여기 효율하지 특히 ​​우려, 하나의 방법입니다,하지만 바보 효율성이 많다는 중 하나를 사람이 길을 따라 문자가있는 인덱스를 ... 구축, 원래의 문자열 배열 문자를 만들

NSString *string = @"e04325ca24cf20ac6bd6ebf73c376b20ac57192dad83b22602264e92dac076611b51142ae12d2d92022eb2c77f"; 
NSMutableArray *chars = [@[] mutableCopy]; 
NSMutableArray *letterIndexes = [@[] mutableCopy]; 

for (int i=0; i<string.length; i++) { 
    unichar ch = [string characterAtIndex:i]; 
    // add each char as a string to a chars collection 
    [chars addObject:[NSString stringWithFormat:@"%c", ch]]; 
    // record the index of letters 
    if ([[NSCharacterSet letterCharacterSet] characterIsMember:ch]) { 
     [letterIndexes addObject:@(i)]; 
    } 
} 

이제 임의의 문자를 대문자로 결정하기 위해 letterIndexes에서 임의로 선택합니다.

int charsToUppercase = 12; 

for (int i=0; i<charsToUppercase && letterIndexes.count; i++) { 
    NSInteger randomLetterIndex = arc4random_uniform((u_int32_t)(letterIndexes.count)); 
    NSInteger indexToUpdate = [letterIndexes[randomLetterIndex] intValue]; 
    [letterIndexes removeObjectAtIndex:randomLetterIndex]; 

    [chars replaceObjectAtIndex:indexToUpdate withObject:[chars[indexToUpdate] uppercaseString]]; 
} 

공지 사항 letterIndexes.count&& 검사를 ... 대문자로 해당 인덱스에 chars 배열의 구성원을 변환합니다. 이렇게하면 charsToUppercasechars의 수를 초과하는 상황을 막을 수 있습니다. 대문자로의 변환의 상한선은 원래 문자열에있는 모든 문자입니다.

이제 남은 모든 문자열로 chars 배열에 가입하는 것입니다 ...

NSString *result = [chars componentsJoinedByString:@""]; 
NSLog(@"%@", result); 

편집 당신은 대신 charsToUppercase 입력 매개 변수의, 확률을 주어, 영업 이익 의견 토론을 할 수 찾고 대문자 변경을 입력으로 사용합니다. 즉

NSString *string = @"e04325ca24cf20ac6bd6ebf73c376b20ac57192dad83b22602264e92dac076611b51142ae12d2d92022eb2c77f"; 

float upperCaseProbability = 0.5; 
NSMutableString *result = [@"" mutableCopy]; 

for (int i=0; i<string.length; i++) { 
    NSString *chString = [string substringWithRange:NSMakeRange(i, 1)]; 
    BOOL toUppercase = arc4random_uniform(1000)/1000.0 < upperCaseProbability; 

    if (toUppercase) { 
     chString = [chString uppercaseString]; 
    } 
    [result appendString:chString]; 
} 
NSLog(@"%@", result); 

그러나이 모든 문자가 아닌 임의의 문자에 해당 대문자 확률을 가정 ... 덜 데이터 변환 가진 단일 루프에이 아이디어를 압축하는 것, 그래서 소정의 횟수에 포함되지 않습니다 케이스를 바꾸는 편지의.

+0

@danh에게 감사드립니다. 두 가지 답변 모두 트릭을 수행해야하는 흥미로운 접근 방식입니다. – Tiago