2

我想要一个从字符串中删除随机字符集并将它们替换为“_”的函数。例如。创造一种填空式的情况。我现在拥有它的方式有效,但它并不聪明。此外,我不想用空格替换空格(正如您在 while 循环中看到的那样)。关于更有效的方法的任何建议?

blankItem = @"Remove Some Characters";
for(int j=0;j<totalRemove;j++)
{
    replaceLocation=arc4random() % blankItem.length;
    while ([blankItem characterAtIndex:replaceLocation] == '_' || [blankItem characterAtIndex:replaceLocation] == ' ') {
         replaceLocation=arc4random() % blankItem.length;
    }
   blankItem= [blankItem stringByReplacingCharactersInRange:NSMakeRange(replaceLocation, 1) withString:@"_"];
}

我的问题在于效率方面的 for 和 while 循环。但是,也许效率不是这么小的东西的本质?

4

1 回答 1

1

如果与字符串的长度相比,要删除/替换的字符数很小,那么您的解决方案很好,因为 while 循环中“冲突”的概率很小。您可以通过使用单个可变字符串而不是在每个步骤中分配新字符串来改进该方法:

NSString *string = @"Remove Some Characters";
int totalRemove = 5;

NSMutableString *result = [string mutableCopy];
for (int j=0; j < totalRemove; j++) {
    int replaceLocation;
    do {
        replaceLocation = arc4random_uniform((int)[result length]);
    } while ([result characterAtIndex:replaceLocation] == '_' || [result characterAtIndex:replaceLocation] == ' ');
    [result replaceCharactersInRange:NSMakeRange(replaceLocation, 1) withString:@"_"];
}

如果要删除/替换的字符数与字符串的长度大致相同,那么不同的算法可能会更好。

以下代码使用C 编程语言中整数数组中的唯一随机数的思想,通过对字符串所有字符的单个循环来替换随机位置的字符。

由于您要求不替换空格字符,因此需要额外(第一次)通过。

NSString *string = @"Remove Some Characters";
int totalRemove = 5;

// First pass: Determine number of non-space characters:
__block int count = 0;
[string enumerateSubstringsInRange:NSMakeRange(0, [string length])
                              options:NSStringEnumerationByComposedCharacterSequences
                           usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
    if (![substring isEqualToString:@" "]) {
        count++;
    }
}];

// Second pass: Replace characters at random positions:
__block int c = count; // Number of remaining non-space characters
__block int r = totalRemove; // Number of remaining characters to replace
NSMutableString *result = [string mutableCopy];
[result enumerateSubstringsInRange:NSMakeRange(0, [result length])
                              options:NSStringEnumerationByComposedCharacterSequences
                           usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
   if (![substring isEqualToString:@" "]) {
       // Replace this character with probability r/c:
       if (arc4random_uniform(c) < r) {
           [result replaceCharactersInRange:substringRange withString:@"_"];
           r--;
           if (r == 0) *stop = YES; // Stop enumeration, nothing more to do.
       }
       c--;
   }
}];

此解决方案的另一个优点是它可以正确处理代理项对(例如表情符号)和组合字符序列,即使它们作为两个单独的字符存储在字符串中也是如此。

于 2013-09-01T05:08:42.330 回答