2012-11-13 15 views
12

文字列を指定すると、その文字列に表示される各単語の数を取得する必要があります。そのために、文字列で配列に文字列を抽出して検索しましたが、文字列を直接検索する方が最適です。以下は、私が最初に問題を解決するために書いたコードです。私はよりよい解決策に関する提案をしています。iOS - 文字列内の単語の出現回数を調べる最も効率的な方法

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
  • "である" - 2
  • "テスト" - - 2
  • "のみ" "" 2
  • - 1
+0

メソッドは機能しますか?ドット記号に問題はありませんか?私はあなたが "テスト"を持っているべきだと思います。 「テスト」ではなく、 – Ricardo

答えて

23

これはまさに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]) 
+0

OMG!それは想像以上に簡単です!ありがとうございました! – RyJ

+0

あなたは大歓迎です! – lnafziger

+0

@Inafzingerしかし、私はいくつかのhtmlタグを含むNSStringの単語の数を数えたいと思っています。スキップします。しかし、私もそれらを数えたい。これのための任意のアイデア。 –

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

あなたには注意する必要があります:

  • 句読点。 (他の単語の近く)
  • 大文字の単語とlowerCaseの単語。
+0

私は各単語の数が必要です。文字列の中で、 "これはテストです。これは単なるテストです。" "test"は2、 "this"は2、 "only"は1などを返します。 – RyJ

+0

私の編集を確認してください。 – Peres

1

長い段落の中の単語をループで検索しようとするのは本当に悪い考えです。あなたはそれを行うために正規表現を使用する必要があります!私はそれを学ぶのは初めてでは簡単ではないことを知っていますが、それを知ることは本当に価値があります!この場合を見てくださいUse regular expression to find/replace substring in NSString

関連する問題