【问题标题】:Objective-C: Randomly replace characters in stringObjective-C:随机替换字符串中的字符
【发布时间】:2013-08-31 20:40:24
【问题描述】:

我想要一个函数,它可以从字符串中删除一组随机字符并将它们替换为“_”。例如。创造一种填空式的情况。我现在拥有它的方式有效,但它并不聪明。此外,我不想用空格替换空格(正如您在 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 循环。但是,对于这么小的事情,效率可能不是最重要的吗?

【问题讨论】:

  • blankItem= (NSMutableString *)[blankItem … 似乎表明你相信强制转换会神奇地改变对象的类。幸运的是,您并没有真正使用 blankItem 是可变字符串这一事实,因为您在每次迭代时都分配了一个新字符串。
  • replaceLocation=arc4random() % blankItem.length; -> replaceLocation = arc4random_uniform(blankItem.length);
  • 警告,只有_和空格的字符串会导致无限循环。

标签: objective-c cocoa-touch nsstring


【解决方案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:@"_"];
}

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

以下代码使用Unique random numbers in an integer array in the C programming language的思路替换字符 在随机位置,对字符串的所有字符进行一次循环。

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

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--;
   }
}];

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

【讨论】:

    猜你喜欢
    • 2017-05-20
    • 1970-01-01
    • 2010-10-14
    • 2011-07-28
    • 1970-01-01
    • 1970-01-01
    • 2017-10-22
    • 2011-07-10
    • 1970-01-01
    相关资源
    最近更新 更多