Objective-C Найти наиболее часто используемые слова в строке NSString - PullRequest
7 голосов
/ 11 сентября 2011

Я пытаюсь написать метод:

- (NSDictionary *)wordFrequencyFromString:(NSString *)string {}

, где в возвращаемом словаре будут слова и как часто они использовались в предоставленной строке.К сожалению, я не могу найти способ перебирать слова в строке, чтобы проанализировать каждый из них - только каждый символ, который кажется немного больше работы, чем необходимо.Есть предложения?

Ответы [ 4 ]

8 голосов
/ 11 сентября 2011

NSString имеет метод -enumerateSubstringsInRange:, который позволяет напрямую перечислять все слова, позволяя стандартному API делать все необходимое для определения границ слов и т. Д .:

[s enumerateSubstringsInRange:NSMakeRange(0, [s length])
                      options:NSStringEnumerationByWords
                   usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
                       NSLog(@"%@", substring);
                   }];

В блоке перечисления вы можете использовать любой NSDictionary сслова в качестве ключей и NSNumber в качестве их счетчиков, или используйте NSCountingSet , который обеспечивает необходимую функциональность для счетчиков.

3 голосов
/ 11 сентября 2011

Вы можете использовать componentsSeparatedByCharactersInSet:, чтобы разбить строку, и NSCountedSet будет считать слова для вас.

1) Разбить строку на слова, используя комбинацию знаков препинания, пробела и новой строки:

NSMutableCharacterSet *separators = [NSMutableCharacterSet punctuationCharacterSet];
[separators formUnionWithCharacterSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

NSArray *words = [myString componentsSeparatedByCharactersInSet:separators];

2) Подсчитайте вхождения слов (если вы хотите игнорировать заглавные буквы, вы можете сделать NSString *myString = [originalString lowercaseString]; перед разбиением строки на компоненты):

NSCountedSet *frequencies = [NSCountedSet setWithArray:words];
NSUInteger aWordCount = [frequencies countForObject:@"word"]);

Если вы хотите изменить сигнатуру вашего метода, вы можете просто вернуть подсчитанный набор.

2 голосов
/ 11 сентября 2011

Разделите строку на массив слов, используя сначала -[NSString componentsSeparatedByCharactersInSet:].(Используйте [[NSCharacterSet letterCharacterSet] invertedSet] в качестве аргумента для разделения всех не буквенных символов.)

0 голосов
/ 08 октября 2015

Я использовал следующий подход для получения наиболее распространенного слова из NSString.

-(void)countMostFrequentWordInSpeech:(NSString*)speechString
{
    NSString     *string     = speechString;
    NSCountedSet *countedSet = [NSCountedSet new];
    [string enumerateSubstringsInRange:NSMakeRange(0, [string length])
                               options:NSStringEnumerationByWords | NSStringEnumerationLocalized
                            usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop){

                                    [countedSet addObject:substring];
                            }];
    // NSLog(@"%@", countedSet);
    //Sort CountedSet & get most  frequent common word at 0th index of resultant array
    NSMutableArray *dictArray = [NSMutableArray array];
    [countedSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
        [dictArray addObject:@{@"object": obj,
                               @"count": @([countedSet countForObject:obj])}];
    }];

    NSArray *sortedArrayOfWord= [dictArray sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"count" ascending:NO]]];
    if (sortedArrayOfWord.count>0)
    {
        self.mostFrequentWordLabel.text=[NSString stringWithFormat:@"Frequent Word: %@", [[sortedArrayOfWord[0] valueForKey:@"object"] capitalizedString]];
    }
}

"speechString" - моя строка, из которой я должен получить наиболее часто встречающиеся / распространенные слова.Объект с 0-м индексом массива "sortedArrayOfWord" будет наиболее распространенным словом.

...