2011-09-11 11 views
6

Estoy tratando de escribir un método:Objective-C encontrar las palabras más utilizadas en un NSString

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

en el diccionario vuelto tendrá las palabras y la frecuencia con que se utilizaron en la cadena entregada. Desafortunadamente, parece que no puedo encontrar una manera de iterar a través de las palabras en una cadena para analizar cada una, solo cada carácter que parece un poco más trabajo de lo necesario. ¿Alguna sugerencia?

+2

Tenga en cuenta que esto probablemente es un poco más trabajo de lo que suponía si desea que sea algo más que increíblemente simple. ¿Los guiones marcan el final de las palabras? Emdashes? ¿Qué hay del japonés は? – Chuck

Respuesta

8

NSString tiene -enumerateSubstringsInRange: método que permite enumerar todas las palabras directamente, dejando API estándar para hacer todo lo necesario para definir los límites de palabras, etc:

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

En el bloque de enumeración puede utilizar cualquiera NSDictionary con palabras como llaves y NSNumber como sus conteos, o use NSCountedSet que proporciona la funcionalidad requerida para conteos.

2

Primero divida la cadena en una matriz de palabras usando -[NSString componentsSeparatedByCharactersInSet:]. (Use [[NSCharacterSet letterCharacterSet] invertedSet] como argumento para dividir en todos los caracteres que no sean letras.)

+0

Luego, simplemente use las palabras (elementos) en la matriz como la clave y un NSNumber como valor para su diccionario. Esto simplifica su trabajo de comparación de cadenas: NSDictionary lo hará por usted. – FeifanZ

3

Puede usar componentsSeparatedByCharactersInSet: para dividir la cadena y NSCountedSet contará las palabras por usted.

1) Dividir la cadena en palabras usando una combinación de la puntuacion, espacios en blanco y carácter de línea fija:

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

NSArray *words = [myString componentsSeparatedByCharactersInSet:separators]; 

2) contar las apariciones de las palabras (si quieres hacer caso omiso de las mayúsculas, se puede NSString *myString = [originalString lowercaseString]; hacer antes de dividir la cadena en componentes):

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

Si usted está dispuesto a cambiar su método de firma, puede simplemente devolver el conjunto contado.

0

Utilicé el siguiente enfoque para obtener la palabra más común de 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" es mi cadena de la que tengo que obtener las palabras más frecuentes/comunes. Objeto en el 0 ° índice de la matriz "sortedArrayOfWord" sería la palabra más común.

Cuestiones relacionadas