如何从NSString中正确随机化字母

我正在创建一个单词扰码器,我有问题随机化字母。 当字母随机化时,它没有意义。

例如,PARK这个词显示为AAPA。 因此,正如您所知,当需要解读时,对用户没有意义。

只是你知道,我正在使用.plist文件来保存单词。

这是我用来随机化字母的代码:

_words = [NSMutableArray arrayWithCapacity:scramblelength]; for (int i=0;i<scramblelength;i++) { NSString *letter = [scramble substringWithRange:[scramble rangeOfComposedCharacterSequenceAtIndex:arc4random()%[scramble length]]]; 

然后,我正在创建UIImageViews来显示乱码:

  if (![letter isEqualToString:@""]) { GameView *boxes = [[GameView alloc] initWithLetter:letter andSideLength:boxSide]; boxes.center = CGPointMake(xOffset + i*(boxSide + kTileMargin), kScreenHeight/4*3); [self.scrambleView addSubview:boxes]; [_words addObject:boxes]; 

我在这做错了什么? 我希望拼写单词中的字母有意义。

请帮忙,我被困在这一个!

谢谢!

只要你的字符串长度适合32位,这应该没问题。 如果没有,我会用C ++中的统一随机数生成器替换arc4random_uniform ,并将其编译为Objective-C ++模块。

代码简单地遍历字符串,并使用来自相同字符串的一些随机组合字符序列交换每个组合字符序列。

对不起,这就是当你傲慢并只输入代码时会发生什么。 如果你遇到这个问题,请告诉我……

对于更大的字符串,有一种更有效的方法,但这似乎可以解决问题。

NSMutableString类别……

 @interface NSMutableString (Scramble) - (void)scramble; @end @implementation NSMutableString (Scramble) static void swapRanges(NSMutableString *string, NSRange iRange, NSRange jRange) { // Need to replace the "trailing" component first if (NSEqualRanges(iRange, jRange)) return; if (iRange.location > jRange.location) { NSRange tmpRange = iRange; iRange = jRange; jRange = tmpRange; } NSString *iString = [self substringWithRange:iRange]; NSString *jString = [self substringWithRange:jRange]; [string replaceCharactersInRange:jRange withString:iString]; [string replaceCharactersInRange:iRange withString:jString]; } - (void)scramble { for (NSUInteger i = 0; i < self.length; ++i) { NSRange iRange = [self rangeOfComposedCharacterSequenceAtIndex:i]; NSUInteger j = arc4random_uniform(self.length); NSRange jRange = [self rangeOfComposedCharacterSequenceAtIndex:j]; swapRanges(self, iRange, jRange); } } @end 

NSString类别......

 @interface NSString (Scramble) - (NSString*)scrambledString; @end @implementation NSString (Scramble) - (NSString *)scrambledString { NSMutableString *result = [self mutableCopy]; [result scramble]; return [result copy]; } @end 

样品使用......

 [someMutableString scramble]; NSString *mixedUp = [someString scrambledString]; 

或者,如果您熟悉C ++,请转换为std::wstring ,调用std::random_shuffle ,然后将其转换为NSString 。 使用久经考验的经过validation的代码可以减少很多错误。

当你收到一封随机字母时,你需要做一些事情来从你的NSMutableArray中删除那个字母(即按顺序时单词的字母)。 因此,当您遍历单词时,每次剩余的字符较少。 现在,从您有限的代码块(第一个)开始,您似乎可能没有这样做。 你想要“[_words removeObjectAtIndex:letterIndex]”这样的东西,你也想要从数字中删除数字,同时从数组中删除项目:for(int i = [_ words count]; i> [_words count ]; i–)因为你需要从4个字母到0个字母。

所以,我确信有更有效的方法可以做到这一点,但我会遵循不优化的规则,直到你需要为止。 考虑到这一点,此代码似乎正常工作:

 - (NSString *)scrambleWord:(NSString *)word { NSMutableArray *letterArray = [self letterArrayFromWord:word]; NSMutableString *returnValue = [[NSMutableString alloc] init]; do { int randomIndex = arc4random() % letterArray.count; [returnValue appendString:letterArray[randomIndex]]; [letterArray removeObjectAtIndex:randomIndex]; if (letterArray.count == 1) { [returnValue appendString:letterArray[0]]; break; } } while (YES); if ([[returnValue copy] isEqualToString:word]) { return [self scrambleWord:word]; } else { return [returnValue copy]; } } - (NSMutableArray *)letterArrayFromWord:(NSString *)word { NSMutableArray *array = [NSMutableArray array]; for (int i = 0; i < word.length; i = i + 1) { [array addObject:[NSString stringWithFormat:@"%C", [word characterAtIndex:i]]]; } return array; }