È possibile risolvere questo problema utilizzando Dynamic Programming e Hashing.
Calcolare l'hash di ogni parola nel dizionario. Usa la funzione di hash che ti piace di più. Vorrei usare qualcosa come (a1 * B^(n - 1) + a2 * B^(n - 2) + ... + an * B^0)% P, dove a1a2 ... an è una stringa, n è la lunghezza della stringa, B è la base del polinomio e P è un numero primo grande. Se si ha il valore hash di una stringa a1a2 ... a è possibile calcolare il valore hash della stringa a1a2 ... ana (n + 1) in tempo costante: (hashValue (a1a2 ... an) * B + a (n + 1))% P.
La complessità di questa parte è O (N * M), dove N è il numero di parole nel dizionario e M è la lunghezza della parola più lunga nel dizionario.
Poi, utilizzare una funzione DP come questo:
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 complessità di questo algoritmo è O (N * M), dove N è la lunghezza della stringa e M è la lunghezza della parola più lunga nel dizionario o O (N^2), a seconda che tu abbia codificato il miglioramento o meno.
Quindi la complessità totale dell'algoritmo sarà: O (N1 * M) + O (N2 * M) (o O (N2^2)), dove N1 è il numero di parole nel dizionario, M è la lunghezza della parola più lunga nel dizionario e N2 è la lunghezza della stringa).
Se non è possibile pensare ad una bella funzione di hash (dove non ce ne sono di collisione), altra soluzione possibile è quella di utilizzare Tentativi o un trie Patricia (se la dimensione del trie normale è molto grande) (non potevo link per questi argomenti perché la mia reputazione non è abbastanza alta per pubblicare più di 2 link). Ma in questo modo, la complessità del tuo algoritmo sarà O (N * M) * O (tempo necessario per trovare una parola nel trie), dove N è la lunghezza della stringa e M è la lunghezza della parola più lunga nel dizionario
Spero che sia d'aiuto, e mi scuso per il mio povero inglese.
Correggimi se ho torto, ma la tua soluzione non è polinomiale. È possibile risolverlo al massimo in O (n^2) usando trie e DP (in realtà O (k) dove k è la lunghezza della parola più lunga nel dizionario). Fammi sapere se hai bisogno della risposta. – ElKamina
@ElKamina Grazie. Mi piacerebbe sentire la soluzione DP – Michael