如何快速打乱NSString的顺序?

3

有没有现成的方法可以改变现有NSString或NSMutableString字符的顺序?我已经有一种解决方法,但如果有现成的方法就更好了。

例如,给定字符串“HORSE”,是否有一种方法可以返回“ORSEH”、“SORHE”、“ROHES”等字符串?

2个回答

5
考虑以下代码:
.h文件:
@interface NSString (Scrambling)

+ (NSString *)scrambleString:(NSString *)toScramble;

@end

.m文件:

@implementation NSString (Scrambling)

+ (NSString *)scrambleString:(NSString *)toScramble {
   for (int i = 0; i < [toScramble length] * 15; i ++) {
      int pos = arc4random() % [toScramble length];
      int pos2 = arc4random() % ([toScramble length] - 1);
      char ch = [toScramble characterAtIndex:pos];
      NSString *before = [toScramble substringToIndex:pos];
      NSString *after = [toScramble substringFromIndex:pos + 1];
      NSString *temp = [before stringByAppendingString:after];
      before = [temp substringToIndex:pos2];
      after = [temp substringFromIndex:pos2];
      toScramble = [before stringByAppendingFormat:@"%c%@", ch, after];
   }
   return toScramble;
}

@end

虽然代码不是最美观的,但它能够完成工作。可能有一种(const char *)的方法可以做到这一点,但对我来说,这个方法已经足够好了。在我的Mac上进行快速测试显示执行时间为0.001021秒。

用法:

NSString *scrambled = [NSString scrambleString:otherString];

代码改编自另一种语言/伪代码


如果你在10.7或iOS 4.3+上运行代码,arc4random_uniform(maxIntIndex)是更好的随机数生成器。但如果你需要支持旧版本,arc4random()仍然不错。 - Jack Lawrence
1
啊,因为我是在编译10.5版,所以它没有出现在“建议”菜单中。知道了就好。 - Glenn Smith
@HiGuy'CouleeApps'Smith,感谢您的评论,但我在使用时遇到了问题:语义问题:找不到类方法'+scrambleString:'(返回类型默认为'id')。您有什么想法可以帮我解决吗?我已经将它放在头文件和实现文件中了。 - Bob-ob
这意味着它找不到该方法。请确保您已经#import了.h文件,并且该方法在.h文件的"@interface NSString (Scrambling)"下被指定。 - Glenn Smith
1
为了使其更好地工作,使用更多字符,请将“%c”替换为“%C”,并将“ch”的类型更改为“unichar”(这是“characterAtIndex:”的返回类型)。 - rmaddy
这是一个类别还是一个类扩展?我是新手。 - temporary_user_name

3
你可以使用Durstenfeld的变体 Fisher-Yates Shuffle
对于非常长的字符串,您可以通过将unichars复制到unichar缓冲区中,然后使用C或C ++方法交换字符来执行转换,从而节省大量CPU时间和分配。请注意,UTF8String不是您想要获取的缓冲区,也不应该对其进行改变。然后从洗牌的缓冲区创建(或设置)一个新的NSString。
有关Fisher Yates算法以及C和C ++实现的更多信息 可以在此处找到

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接