iOS – 在string中查找单词出现次数的最有效方法

给定一个string,我需要获得该string中出现的每个单词的计数。 为了这样做,我把string提取成一个数组,然后按照这个方式进行search,但是我觉得直接searchstring是最理想的。 下面是我最初编写来解决问题的代码。 虽然我提出了更好的解决scheme的build议。

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); 

例:

起始string:
“这是一个考验,这只是一个考验。”

结果:

  • “这个” – 2
  • “是” – 2
  • “a2
  • “testing” – 2
  • “只有1个

这正是NSCountedSet的用途。

你需要将string拆分成单词(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]) 

如果我不得不猜测,我会说NSRegularExpression 。 喜欢这个:

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

那个片段是从这里拿走的。


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

你应该小心:

  • 标点符号。 (接近其他词)
  • 大写单词vs小写单词。

我认为,这是一个非常糟糕的主意,你试图在循环中search长篇文字。 你应该使用正则expression式来做到这一点! 我知道第一次学习它并不容易,但真的值得去了解它! 看看这种情况使用正则expression式来查找/replaceNSString中的子string