Jedną opcją byłoby przechowywanie wszystkich poprawnych angielskich słów w trie. Gdy już to zrobisz, możesz zacząć przechodzić triest od korzenia w dół, podążając za literami w łańcuchu. Gdy znajdziesz węzeł, który jest oznaczony jako słowo, masz dwie opcje:
- złamać wejście w tym momencie, czy
- dalej rozszerzając słowo.
Możesz stwierdzić, że udało Ci się znaleźć dopasowanie po tym, jak wprowadziłeś dane do zestawu słów, które są legalne i nie zostały pozostałe. Ponieważ przy każdej literze masz jedną wymuszoną opcję (albo budujesz słowo, które nie jest poprawne i powinno zostać przerwane - lub - możesz kontynuować rozszerzanie słowa) lub dwie opcje (podzielone lub kontynuuj), możesz zaimplementować tę funkcję za pomocą wyczerpującego rekurencji:
PartitionWords(lettersLeft, wordSoFar, wordBreaks, trieNode):
// If you walked off the trie, this path fails.
if trieNode is null, return.
// If this trie node is a word, consider what happens if you split
// the word here.
if trieNode.isWord:
// If there is no input left, you're done and have a partition.
if lettersLeft is empty, output wordBreaks + wordSoFar and return
// Otherwise, try splitting here.
PartitinWords(lettersLeft, "", wordBreaks + wordSoFar, trie root)
// Otherwise, consume the next letter and continue:
PartitionWords(lettersLeft.substring(1), wordSoFar + lettersLeft[0],
wordBreaks, trieNode.child[lettersLeft[0])
W patologicznie najgorszym przypadku będzie to lista wszystkich partycji napisu, który może t wykładniczo długo. Dzieje się tak jednak tylko wtedy, gdy możesz podzielić łańcuch na wiele różnych sposobów, zaczynając od prawidłowych angielskich słów i jest mało prawdopodobne, aby wystąpił w praktyce. Jeśli łańcuch ma wiele partycji, możemy spędzić dużo czasu na ich znajdowaniu. Rozważmy na przykład ciąg "dotheredo". Możemy podzielić to na wiele sposobów:
do the redo
do the red o
doth ere do
dot here do
dot he red o
dot he redo
Aby tego uniknąć, warto wnieść ograniczenie liczby odpowiedzi, Raport, może dwa lub trzy.
Ponieważ odcięliśmy rekursję, gdy wychodzimy z trie, jeśli kiedykolwiek spróbujemy podziału, który nie pozostawi pozostałej części łańcucha, to wykryjemy to dość szybko.
Mam nadzieję, że to pomoże!
Wiem, że to stary post, ale miałem pytanie po przeczytaniu Twojego świetnego posta na blogu. O (2^n) wciąż jest dla mnie zagadką dla ogólnego rozwiązania, choć intuicyjnie może to mieć sens. Próbowałem użyć conbinatorics, aby go rozwiązać, a także rozwiązać problem powtarzania się (T (n) = n * T (n-1) + O (k)), ale mogę uzyskać tylko powiązanie obejmujące iloczyn n! z funkcją Gamma. Czy próbowałeś także rozwiązać problem powtarzania się O (2^n)? – ak3nat0n
Czy to pomaga? https://en.wikipedia.org/wiki/Composition_%28combinatorics%29 –