Reorganice las letras de la matriz y verifique si la disposition está en order

Estoy haciendo una aplicación de ios en la que ingresas 9 lettes y generará anagtwigs de esas 9 letras. Es como la palabra objective, o palabra de 9 letras en el papel. Me gusta este enlace:

http://nineletterword.tompaton.com/

No solo proporciona anagtwigs para 9 letras, lo hará por 4 letras, 5 letras, 6 letras … todas las cuales contienen al less la letra del medio.

Quiero convertirlo en una aplicación sin connection , por lo que no quiero hacer reference a ningún website ni usar un json en línea …

¿Cómo verifico si una matriz de las 9 letras se puede reorganizar en una palabra que se encuentra en un dictionary inglés que he descargado?

Por ejemplo, tengo la input de (a, b, a, n, D , o, n, e, d): ¿cómo obtendré la salida de 4 letras o más que son palabras en inglés en una matriz llamada "Diccionario inglés" que debe contener la letra del medio "D" – como "abandonar", "vínculo", "muerto" …

¿Es el mejor método muchos, muchos loops y si hay declaraciones o hay algo en xcode / objective c que puedo usar para get la list de 4 letras y luego tener todos los arreglos posibles …

Aclamaciones

Permítanme proponer un algorithm diferente que depende de una búsqueda, no una búsqueda a través de una matriz.

Preparar:

Iterar sobre las palabras en el dictionary. Para cada palabra, cree una cadena con los mismos caracteres, orderados alfabéticamente. Utilizando esta cadena como key, cree un dictionary de matrices de las palabras originales.

Uso:

Ahora puede hacer el control de cualquier combinación de caracteres muy rápidamente: simplemente ordere los caracteres como se ve arriba y mire la key resultante en el map.

Ejemplo:

matriz original: ( bond, Mary, army )

anagtwig map de búsqueda:

 { bdno : ( bond ), amry : ( Mary, army ), } 

Usando este map, es muy rápido comprobar anagtwigs de cualquier palabra. No se necesita iteración sobre la matriz de dictionary.

Editar:

Mi algorithm propuesto se divide en tres partes:

  1. Un método de configuration para build el map de búsqueda desde un dictionary de objects: anagramMap
  2. Un método para calcular la key orderada por caracteres: anagramKey
  3. Un algorithm que encuentra todas las permutaciones de los caracteres contenidos en la palabra de nueve letras y busca las palabras en el map: findAnagrams .

Aquí hay una implementación de los tres methods como una categoría en NSString :

 @interface NSString (NSStringAnagramAdditions) - (NSSet *)findAnagrams; @end @implementation NSString (NSStringAnagramAdditions) + (NSDictionary *)anagramMap { static NSDictionary *anagramMap; if (anagramMap != nil) return anagramMap; // this file is present on Mac OS and other unix variants NSString *allWords = [NSString stringWithContentsOfFile:@"/usr/share/dict/words" encoding:NSUTF8StringEncoding error:NULL]; NSMutableDictionary *map = [NSMutableDictionary dictionary]; @autoreleasepool { [allWords enumerateLinesUsingBlock:^(NSString *word, BOOL *stop) { NSString *key = [word anagramKey]; if (key == nil) return; NSMutableArray *keyWords = [map objectForKey:key]; if (keyWords == nil) { keyWords = [NSMutableArray array]; [map setObject:keyWords forKey:key]; } [keyWords addObject:word]; }]; } anagramMap = map; return anagramMap; } - (NSString *)anagramKey { NSString *lowercaseWord = [self lowercaseString]; // make sure to take the length *after* lowercase. it might change! NSUInteger length = [lowercaseWord length]; // in this case we're only interested in anagrams 4 - 9 characters long if (length < 4 || length > 9) return nil; unichar sortedWord[length]; [lowercaseWord getCharacters:sortedWord range:(NSRange){0, length}]; qsort_b(sortedWord, length, sizeof(unichar), ^int(const void *aPtr, const void *bPtr) { int a = *(const unichar *)aPtr; int b = *(const unichar *)bPtr; return b - a; }); return [NSString stringWithCharacters:sortedWord length:length]; } - (NSSet *)findAnagrams { unichar nineCharacters[9]; NSString *anagramKey = [self anagramKey]; // make sure this word is not too long/short. if (anagramKey == nil) return nil; [anagramKey getCharacters:nineCharacters range:(NSRange){0, 9}]; NSUInteger middleCharPos = [anagramKey rangeOfString:[self substringWithRange:(NSRange){4, 1}]].location; NSMutableSet *anagrams = [NSMutableSet set]; // 0x1ff means first 9 bits set: one for each character for (NSUInteger i = 0; i <= 0x1ff; i += 1) { // skip permutations that do not contain the middle letter if ((i & (1 << middleCharPos)) == 0) continue; NSUInteger length = 0; unichar permutation[9]; for (int bit = 0; bit <= 9; bit += 1) { if (i & (1 << bit)) { permutation[length] = nineCharacters[bit]; length += 1; } } if (length < 4) continue; NSString *permutationString = [NSString stringWithCharacters:permutation length:length]; NSArray *matchingAnagrams = [[self class] anagramMap][permutationString]; for (NSString *word in matchingAnagrams) [anagrams addObject:word]; } return anagrams; } @end 

Asumiendo una cadena de testing en una variable llamada nineletters , se registran los valores posibles usando:

 for (NSString *anagram in [nineletters findAnagrams]) NSLog(@"%@", anagram); 

Primero necesitas un método para verificar si una palabra es un anagtwig de una segunda palabra. Existen muchas soluciones posibles (busque "anagtwig Objectivo-C"). Este es esencialmente el método de https://stackoverflow.com/a/13465672/1187415 , escrito de manera ligeramente diferente:

 - (BOOL)does:(NSString*)longWord contain:(NSString *)shortWord { NSMutableString *longer = [longWord mutableCopy]; __block BOOL retVal = YES; // Loop over all characters (letters) in shortWord: [shortWord enumerateSubstringsInRange:NSMakeRange(0, [shortWord length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) { // Check if letter occurs in longer word: NSRange letterRange = [longer rangeOfString:substring]; if (letterRange.location != NSNotFound) { // Yes. Remove from longer word and continue. [longer deleteCharactersInRange:letterRange]; } else { // No. Set return value to NO and quit the loop. retVal = NO; *stop = YES; } }]; return retVal; } 

Ejemplos:

  • [self does:@"abandoned" contain:@"bond"] = YES
  • [self does:@"abandoned" contain:@"sea"] = NO , porque no hay "s" en la primera palabra.
  • [self does:@"abandoned" contain:@"noon"] = NO , porque "mediodía" tiene 2 letras "o", pero la primera palabra tiene solo una "o".

Luego puede proceder de la siguiente manera:

 NSArray *englishWords = ...; // Your array of english words NSString *inputWord = @"abandoned"; // The input string NSString *middleLetter = [inputWord substringWithRange:NSMakeRange([inputWord length]/2, 1)]; NSPnetworkingicate *pnetworkingicate = [NSPnetworkingicate pnetworkingicateWithBlock:^BOOL(NSString *word, NSDictionary *bindings) { // Word must have at least 4 letters: if ([word length] < 4) return NO; // Word must contain the middle letter: if ([word rangeOfString:middleLetter].location == NSNotFound) return NO; // Word must contain only letters of the input word: if (![self does:inputWord contain:word]) return NO; return YES; }]; NSArray *matchingWords = [englishWords filtenetworkingArrayUsingPnetworkingicate:pnetworkingicate]; NSLog(@"%@", matchingWords); 
Intereting Posts