¿Cómo search todas las palabras de la cadena de input en ios?

Digo, tengo vocabulario (alnetworkingedor de 100000 palabras) y palabra ("string de input"). Asi que:

Necesito generar todas las palabras desde "inputstring" como "input", "string", "put", "strinpg" etc. Y luego necesito verificarlas en mi vocabulario. ¿Podrías decir algún buen algorithm para eso? Porque solo tengo idea con:

  1. Búsqueda recursiva de todas las combinaciones posibles en el paso 1
  2. Utilizando NSPnetworkingicates para filtrarlos en mi vocabulario.

Estás en el path correcto con NSPnetworkingicate . Y la fase que está buscando es búsqueda fault tolerant y se resuelve mediante la distancia Levenshtein . Lo que básicamente necesitas hacer es hacer un || Combinación con consultas en consultas individuales.

Supongamos que tiene todas sus palabras en NSArray . Debe llamar a un método filtenetworkingArrayUsingPnetworkingicate: en él, PERO no es súper fácil build un pnetworkingicado como ese.

Entonces sus requisitos son:

  1. Palabra de búsqueda puede ser parte de una palabra más grande.
  2. El usuario puede escribir mal palabra

La primera parte es bastante fácil, todo lo que necesitas hacer es poner CONTAINS a tu pnetworkingicado. La segunda parte debería ser similar a ?tring or s?ring or st?ing... y puede buildse fácilmente con. Puedes experimentar con varios numbers de ? firme y vea qué coincide con sus criterios.

Intenté con NSRegularExpression ya que CoreData y NSPnetworkingicate parece administrarlos, pero no pude tener una solución funcional (tal vez vinculada a mi no experiencia en Regex, pero podría ser una ventaja). Lo intenté también con NSCharacterSet , pero no pudo decir que el número de apariciones era correcto ..

Quizás esta no sea la manera más sexy de hacerlo, pero aquí puedes hacer lo siguiente:

 NSString *searchedWord = @"inputString"; NSPnetworkingicate *pnetworkingicate = [NSPnetworkingicate pnetworkingicateWithBlock:^BOOL(NSString *evaluatedObject, NSDictionary *bindings) { for (NSUInteger index = 0; index < [evaluatedObject length]; index++) { NSString *subString = [evaluatedObject substringWithRange:NSMakeRange(index, 1)]; NSUInteger numberOfOccurrencesInSearchWord = [self occurrencesOfSubString:subString inString:searchedWord]; NSUInteger numberOfOccurrencesInCurrentWord = [self occurrencesOfSubString:subString inString:evaluatedObject]; if (numberOfOccurrencesInCurrentWord > numberOfOccurrencesInSearchWord) return FALSE; } return TRUE; }]; //Apply this pnetworkingicate to your fetch 

occurrencesOfSubString:inString: en la class, pero podría ser una categoría en NSString por ejemplo. También podría rangeOfString:option:range con rangeOfString:option:range si los prefiere a NSRegularExpression . Fuente del código (ligeramente modificado)

 -(NSUInteger)occurrencesOfSubString:(NSString *)subString inString:(NSString *)string { NSUInteger numberOfMatches = 0; NSError *error = nil; NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:subString options:NSRegularExpressionCaseInsensitive error:&error]; if (!error) numberOfMatches = [regex numberOfMatchesInString:string options:0 range:NSMakeRange(0, [string length])]; return numberOfMatches; } 

Nota: para evitar demasiados loops, es posible que desaparezca el object evaluatedObject para no verificar el valor repetido. Por ejemplo, si evaluatedObject = @"aaa" , se verá 3 veces para "a". Eliminar los valores duplicates puede mejorar la velocidad. Aquí hay una solución . Entonces, el código estaría en el bloque de pnetworkingicados:

 NSString *evaluatedWithoutRepeat = [evaluatedObject removeDuplicatedCharacters]; for (NSUInteger index = 0; index <= [evaluatedWithoutRepeat length]; index ++) { NSString *subString = [evaluatedWithoutRepeat substringWithRange:NSMakeRange:(index,1)]; //The rest would be the same. } 

WorkingTest:

 NSArray *testValues = @[@"inputString", @"input", @"string", @"put", @"strinpg", @"Stringpg", @"stringNOTWANTED"]; NSLog(@"AllValues: %@", testValues); NSLog(@"Test: %@", [testValues filtenetworkingArrayUsingPnetworkingicate:pnetworkingicate]); 

Salida:

 > AllValues: ( inputString, input, string, put, strinpg, Stringpg, stringNOTWANTED ) > Test: ( inputString, input, string, put, strinpg ) 

Parece que quieres insert tu list de vocabulario en un trie. Esto le dará una estructura de datos que luego puede verificar rápidamente para encontrar todas las subcadenas en su input que están presentes en su vocabulario.

Suponiendo que está construyendo el trie una vez y revisando muchas cadenas de input diferentes, esto será mucho más rápido que comenzar al encontrar combinatoriamente todas las subcadenas de su input. (Esta velocidad viene al costo de la memory para el trie.)

No estoy seguro de si hay un algorithm especial para resolver su problema. Pero las posibilidades son limitadas si tiene que resolverlo con Core Data Fetch Requests. Lo haría así:

 - (NSArray *)getWordsFromString:(NSString *)input{ NSMutableArray *result = [NSMutableArray new]; NSUInteger *startIndex = 0; for (NSUInteger i = 0; i < input.length ; i++){ NSString *substring = [input substringWithRange:NSMakeRange(*startIndex, i)]; NSPnetworkingicate *pnetworkingicate = [NSPnetworkingicate pnetworkingicateWithFormat:@"word == %@", substring]; NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Word"]; fetchRequest.pnetworkingicate = pnetworkingicate [fetchRequest setIncludesPropertyValues:NO]; [fetchRequest setIncludesSubentities:NO]; NSArray *fetchResult = fetch result with pnetworkingicate if (fetchResult.count > 0){ [result addObject:substring]; startIndex = i; } } return result; } 
 NSMutableArray *foundWords = [NSMutableArray new]; for (NSString *knownWord in vocabulary) { if ([input rangeOfString:knownWord].location != NSNotFound) { [foundWords addObject:knownWord]; } } 

Puedes hacerlo preparando el vocabulario. Debe include solo palabras que comienzan con letras que están contenidas por palabra de input.