12

文字列が与えられた場合、その文字列に表示される各単語の数を取得する必要があります。そのためには、文字列を単語ごとに配列に抽出して検索しましたが、文字列を直接検索する方が最適だと感じています。以下は、問題を解決するために私が最初に書いたコードです。しかし、私はより良い解決策についての提案を求めています。

NSMutableDictionary *sets = [[NSMutableDictionary alloc] init];

NSString *paragraph = [[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"text" ofType:@"txt"] encoding:NSUTF8StringEncoding error:NULL];

NSMutableArray *words = [[[paragraph lowercaseString] componentsSeparatedByString:@" "] mutableCopy];

while (words.count) {
    NSMutableIndexSet *indexSet = [[NSMutableIndexSet alloc] init];
    NSString *search = [words objectAtIndex:0];
    for (unsigned i = 0; i < words.count; i++) {
        if ([[words objectAtIndex:i] isEqualToString:search]) {
            [indexSet addIndex:i];
        }
    }
    [sets setObject:[NSNumber numberWithInt:indexSet.count] forKey:search];
    [words removeObjectsAtIndexes:indexSet];
}

NSLog(@"%@", sets);

例:

開始文字列:
「これはテストです。これは単なるテストです。」

結果:

  • 「これ」-2
  • 「is」-2
  • 「a」-2
  • 「テスト」-2
  • "たった1つ
4

3 に答える 3

24

これはまさに an のNSCountedSet目的です。

文字列を単語に分割する必要があり (iOS は、句読点を気にする必要がないように関数を提供するのに十分便利です)、それらのそれぞれをカウントされたセットに追加するだけで、数を追跡できます。各オブジェクトがセットに出現する回数:

NSString     *string     = @"This is a test. This is only a test.";
NSCountedSet *countedSet = [NSCountedSet new];

[string enumerateSubstringsInRange:NSMakeRange(0, [string length])
                           options:NSStringEnumerationByWords | NSStringEnumerationLocalized
                        usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop){

                            // This block is called once for each word in the string.
                            [countedSet addObject:substring];

                            // If you want to ignore case, so that "this" and "This" 
                            // are counted the same, use this line instead to convert
                            // each word to lowercase first:
                            // [countedSet addObject:[substring lowercaseString]];
                        }];

NSLog(@"%@", countedSet);

// Results:  2012-11-13 14:01:10.567 Testing App[35767:fb03] 
// <NSCountedSet: 0x885df70> (a [2], only [1], test [2], This [2], is [2])
于 2012-11-13T19:05:58.200 に答える
2

私が推測しなければならないとしたら、私はNSRegularExpressionそれについて言うでしょう。このような:

NSUInteger numberOfMatches = [regex numberOfMatchesInString:string
                                                    options:0
                                                      range:NSMakeRange(0, [string length])];

そのスニペットはhereから取得されました。


編集 1.0:

サー・ティルの言葉に基づいて:

NSString *string = @"This is a test, so it is a test";

NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
NSArray *arrayOfWords = [string componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
for (NSString *word in arrayOfWords)
{
    if ([dictionary objectForKey:word])
    {
        NSNumber *numberOfOccurences = [dictionary objectForKey:word];
        NSNumber *increment = [NSNumber numberWithInt:(1 + [numberOfOccurences intValue])];
        [dictionary setValue:increment forKey:word];
    }
    else
    {
        [dictionary setValue:[NSNumber numberWithInt:1] forKey:word];
    }
}

次の点に注意してください。

  • 句読点。(ほぼ別の言葉)
  • 大文字の単語と小文字の単語。
于 2012-11-13T18:23:17.153 に答える
1

ループで長い段落の中から単語を検索しようとするのは、本当に悪い考えだと思います。そのためには、正規表現を使用する必要があります。初めて学ぶのは簡単ではないことはわかっていますが、それを知ることは本当に価値があります! このケースを見てみましょう正規表現を使用して NSString の部分文字列を検索/置換します

于 2012-11-13T18:36:08.917 に答える