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

このソリューションのもう 1 つの利点は、サロゲート ペア (絵文字など) と構成された文字シーケンスが、文字列内に2 つの別個の文字として格納されている場合でも、正しく処理されることです。

于 2013-09-01T05:08:42.330 に答える