0

コロンで区切られた NSString にいくつかのデータがあります。

@"John:Doe:1970:Male:Dodge:Durango"

この文字列の合計の長さを 100 文字に制限する必要があります。ただし、正しい数のコロンが存在することも確認する必要があります。

文字列を切り捨てるだけでなく、余分なコロンを追加して、反対側の正しい数のフィールドに解析できるようにする合理的な方法は何ですか?

たとえば、私の制限が 18 だった場合、次のようになります。

@"John:Doe:1970:Ma::"

これは、これに関する私自身の最新のパスの更新版です。@blinkenlights アルゴリズムを使用:

+ (NSUInteger)occurrencesOfSubstring:(NSString *)substring inString:(NSString *)string {
    // http://stackoverflow.com/a/5310084/878969
    return [string length] - [[string stringByReplacingOccurrencesOfString:substring withString:@""] length] / [substring length];
}

+ (NSString *)truncateString:(NSString *)string toLength:(NSUInteger)length butKeepDelmiter:(NSString *)delimiter {
    if (string.length <= length)
        return string;
    NSAssert(delimiter.length == 1, @"Expected delimiter to be a string containing a single character");
    int numDelimitersInOriginal = [[self class] occurrencesOfSubstring:delimiter inString:string];

    NSMutableString *truncatedString = [[string substringToIndex:length] mutableCopy];
    int numDelimitersInTruncated = [[self class] occurrencesOfSubstring:delimiter inString:truncatedString];
    int numDelimitersToAdd = numDelimitersInOriginal - numDelimitersInTruncated;
    int index = length - 1;
    while (numDelimitersToAdd > 0) { // edge case not handled here
        NSRange nextRange = NSMakeRange(index, 1);
        index -= 1;
        NSString *rangeSubstring = [truncatedString substringWithRange:nextRange];
        if ([rangeSubstring isEqualToString:delimiter])
            continue;
        [truncatedString replaceCharactersInRange:nextRange withString:delimiter];
        numDelimitersToAdd -= 1;
    }
    return truncatedString;
}

このソリューションは、区切り文字の数が制限よりも少ない CRD のエッジ ケースを処理するとは思わないことに注意してください。

正しい数のコロンが必要な理由は、サーバー上のコードがコロンで分割され、5 つの文字列が返されることを期待しているからです。

コロンで区切られた文字列の構成要素自体にはコロンが含まれていないと想定できます。

4

2 に答える 2

3

現在のアルゴリズムは、最後の文字の 1 つ以上がcolonsToAddコロンである場合、正しい結果を生成しません。

代わりにこのアプローチを使用できます。

  • 文字列を 100 文字で切り取り、文字列をNSMutableString
  • コロンの数を数え、必要な数からその数を引きます
  • 文字列の後ろから始めて、適切な数のコロンが得られるまで、コロン以外の文字をコロンに置き換えます。
于 2013-11-13T19:26:31.193 に答える
2

私は@dasblinkenlightを好む傾向があります。結局のところ、これは単なるアルゴリズムですが、ここにいくつかのコードがあります. いくつかの最新の略記 - 古いコンパイラを使用。ARC を想定。効率的または美しいとは言いませんが、機能し、エッジケース (コロンの繰り返し、制限に対してフィールドが多すぎる) を処理します。

- (NSString *)abbreviate:(NSString *)input limit:(NSUInteger)limit
{
    NSMutableArray *fields = [[input componentsSeparatedByString:@":"] mutableCopy];
    NSUInteger colonCount = fields.count - 1;

    if (colonCount >= limit)
        return [@"" stringByPaddingToLength:limit withString:@":" startingAtIndex:0];

    NSUInteger nonColonsRemaining = limit - colonCount;
    for (NSUInteger ix = 0; ix <= colonCount; ix++)
    {
        if (nonColonsRemaining > 0)
        {
            NSString *fieldValue = [fields objectAtIndex:ix];
            NSUInteger fieldLength = fieldValue.length;
            if (fieldLength <= nonColonsRemaining)
                nonColonsRemaining -= fieldLength;
            else
            {
                [fields replaceObjectAtIndex:ix withObject:[fieldValue substringToIndex:nonColonsRemaining]];
                nonColonsRemaining = 0;
            }
        }
        else
            [fields replaceObjectAtIndex:ix withObject:@""];
    }

    return [fields componentsJoinedByString:@":"];  
}
于 2013-11-13T22:20:50.020 に答える