jke*_*esh 7 shuffle objective-c nsstring
我已经编写了这个函数来调整a的内容NSString,它似乎工作,但它时不时地崩溃.这可能是一种迂回的方式,但我把字符放入一个数组,随机交换数组中的元素,然后将数组转回一个字符串.
我不确定我在做什么不安全会导致它崩溃.我认为可能是我正在设置finalLettersString = result,但我也尝试了,但finalLettersString = [NSString stringWithString:result]也崩溃了.我感到困惑的原因是因为它不会每次都崩溃.我只是按下随机按钮,有时它会崩溃.我应该看的任何地方?
/* This function shuffles the letters in the string finalLettersString */
-(IBAction)shuffleLetters:(id)sender{
int length = [finalLettersString length];
NSMutableArray * letters = [NSMutableArray arrayWithCapacity:length];
NSLog(@"final letters: %@", finalLettersString);
for(int i = 0; i < length; i++){
char ch = [finalLettersString characterAtIndex:i];
NSLog(@"%c", ch);
NSString * cur = [NSString stringWithFormat:@"%c", ch];
[letters insertObject:cur atIndex:i];
}
NSLog(@"LETTERS:: %@", letters);
for(int i = length - 1; i >= 0; i--){
int j = arc4random() % (i + 1);
//NSLog(@"%d %d", i, j);
//swap at positions i and j
NSString * str_i = [letters objectAtIndex:i];
[letters replaceObjectAtIndex:i withObject:[letters objectAtIndex:j]];
[letters replaceObjectAtIndex:j withObject:str_i];
}
NSLog(@"NEW SHUFFLED LETTERS %@", letters);
NSString * result = @"";
for(int i = 0; i < length; i++){
result = [result stringByAppendingString:[letters objectAtIndex:i]];
}
NSLog(@"Final string: %@", result);
finalLettersString = result;
finalLetters.text = finalLettersString;
}
Run Code Online (Sandbox Code Playgroud)
pix*_*eak 11
@ dreamlax代码的变体,不使用char数组.肯定不那么有效.但它没有Unicode问题.
NSMutableString *randomizedText = [NSMutableString stringWithString:currentText];
NSString *buffer;
for (NSInteger i = randomizedText.length - 1, j; i >= 0; i--)
{
j = arc4random() % (i + 1);
buffer = [randomizedText substringWithRange:NSMakeRange(i, 1)];
[randomizedText replaceCharactersInRange:NSMakeRange(i, 1) withString:[randomizedText substringWithRange:NSMakeRange(j, 1)]];
[randomizedText replaceCharactersInRange:NSMakeRange(j, 1) withString:buffer];
}
Run Code Online (Sandbox Code Playgroud)
最好将字符串的内容复制到类型的临时缓冲区中unichar并随机缓冲缓冲区的内容,而不是创建大量的小字符串.
NSUInteger length = [finalLettersString length];
if (!length) return; // nothing to shuffle
unichar *buffer = calloc(length, sizeof (unichar));
[finalLettersString getCharacters:buffer range:NSMakeRange(0, length)];
for(int i = length - 1; i >= 0; i--){
int j = arc4random() % (i + 1);
//NSLog(@"%d %d", i, j);
//swap at positions i and j
unichar c = buffer[i];
buffer[i] = buffer[j];
buffer[j] = c;
}
NSString *result = [NSString stringWithCharacters:buffer length:length];
free(buffer);
// caution, autoreleased. Allocate explicitly above or retain below to
// keep the string.
finalLettersString = result;
Run Code Online (Sandbox Code Playgroud)
您需要注意的几件事情:
Unicode字符串可以包含复合字符和代理项对.将这些转移到最有可能导致无效的字符串.虽然代理对很少见,但是发现字符é由两个字符组成(基本小写字母e和组合的尖锐重音)并不罕见.
对于大字符串,它可能会导致内存问题,因为最终使用的空间是原始字符串的3倍(原始字符串为1倍,我们使用的缓冲区为2倍,新字符串为3倍,然后返回一旦我们释放缓冲区就2×