Puede resolver este problema usando Dynamic Programming y Hashing.
Calcula el hash de cada palabra en el diccionario. Use la función hash que más le guste. Yo usaría algo como (a1 * B^(n - 1) + a2 * B^(n - 2) + ... + an * B^0)% P, donde a1a2 ... an es una cadena, n es la longitud de la cuerda, B es la base del polinomio y P es un número primo grande. Si tiene el valor hash de una cadena a1a2 ... an, puede calcular el valor hash de la cadena a1a2 ... ana (n + 1) en tiempo constante: (hashValue (a1a2 ... an) * B + a (n + 1))% P.
La complejidad de esta parte es O (N * M), donde N es el número de palabras en el diccionario y M es la longitud de la palabra más larga en el diccionario.
continuación, utilizar una función DP como esto:
bool vis[LENGHT_OF_STRING];
bool go(char str[], int length, int position)
{
int i;
// You found a set of words that can solve your task.
if (position == length) {
return true;
}
// You already have visited this position. You haven't had luck before, and obviously you won't have luck this time.
if (vis[position]) {
return false;
}
// Mark this position as visited.
vis[position] = true;
// A possible improvement is to stop this loop when the length of substring(position, i) is greater than the length of the longest word in the dictionary.
for (i = position; position < length; i++) {
// Calculate the hash value of the substring str(position, i);
if (hashValue is in dict) {
// You can partition the substring str(i + 1, length) in a set of words in the dictionary.
if (go(i + 1)) {
// Use the corresponding word for hashValue in the given position and return true because you found a partition for the substring str(position, length).
return true;
}
}
}
return false;
}
La complejidad de este algoritmo es O (N * M), donde N es la longitud de la cadena y M es la longitud de la palabra más larga en el diccionario o O (N^2), dependiendo de si codificó la mejora o no.
Entonces la complejidad total del algoritmo será: O (N1 * M) + O (N2 * M) (o O (N2^2)), donde N1 es el número de palabras en el diccionario, M es la longitud de la palabra más larga en el diccionario y N2 es la longitud de la cadena).
Si no puede pensar en una buena función hash (donde no hay ninguna colisión), otra posible solución es usar Tries o un Patricia trie (si el tamaño del trie normal es muy grande) (No pude No publico enlaces para estos temas porque mi reputación no es lo suficientemente alta como para publicar más de 2 enlaces). Pero en usted usa esto, la complejidad de su algoritmo será O (N * M) * O (Tiempo necesario para encontrar una palabra en el trie), donde N es la longitud de la cadena y M es la longitud de la palabra más larga en el diccionario.
Espero que ayude, y me disculpo por mi pobre inglés.
Corrígeme si me equivoco, pero tu solución no es polinómica. Es posible resolver esto como máximo O (n^2) usando trie y DP (en realidad es O (k) donde k es la longitud de la palabra más larga en el diccionario). Avísame si necesitas la respuesta. – ElKamina
@ElKamina Gracias. Me gustaría escuchar la solución DP – Michael