Szukam struktury danych, która przechowuje zestaw ciągów znaków nad zestawem znaków , zdolną do wykonywania następujących operacji. Oznaczmy D ( S ) , jak w strukturze danych przechowującej zestaw łańcuchy S .
Add-Prefix-Set
na : biorąc pod uwagę pewien zestaw T (prawdopodobnie pustych) ciągów, których rozmiar jest ograniczony stałą, a których długości są ograniczone stałą, zwraca D ( { t s | t ∈ T , s ∈ S } ) . Oba te stałe ograniczające są globalne: są takie same dla wszystkich wejść T .Get-Prefixes
na : return { a | a s ∈ S , a ∈ Σ } . Zauważ, że tak naprawdę nie przeszkadza mi, jaka struktura jest używana dla tego zestawu, o ile mogę wyliczyć jego zawartość w czasie O ( | Σ | ) .Remove-Prefixes
na : zwraca D ( { s | a s ∈ S , a ∈ Σ } ) .Merge
: biorąc pod uwagę i D ( T ) , zwróć D ( S ∪ T ) .
Teraz naprawdę chciałbym wykonać wszystkie te operacje w czasie , ale dobrze mi jest ze strukturą, która wykonuje wszystkie te operacje w czasie o ( n ) , gdzie n jest długością najdłuższego ciągu w Struktura. W przypadku scalania Chciałbym O ( n 1 + n 2 ) czas trwania, w którym n 1 jest brak w pierwszym i n 2 N dla drugiej struktury.
Dodatkowym wymaganiem jest to, że struktura jest niezmienna lub przynajmniej, że powyższe operacje zwracają „nowe” struktury, tak aby wskaźniki do starych nadal działały jak poprzednio.
Uwaga na temat amortyzacji: w porządku, ale musisz uważać na wytrwałość. Ponieważ cały czas ponownie używam starych struktur, będę miał kłopoty, jeśli trafię w najgorszy przypadek jakimś określonym zestawem operacji na tej samej strukturze (ignorując nowe struktury, które tworzy).
Chciałbym użyć takiej struktury w algorytmie analizującym, nad którym pracuję; powyższa struktura zawiera oczekiwany przeze mnie algorytm.
Już rozważałem użycie trie , ale głównym problemem jest to, że nie wiem, jak skutecznie połączyć próby. Jeśli zestaw ciągów znaków Add-Prefix-Set
składa się tylko z ciągów jednoznakowych, możesz przechowywać te zestawy w stosie, co dałoby ci czas uruchamiania dla pierwszych trzech operacji. Jednak to podejście nie działa również w przypadku łączenia.
Na koniec zauważ, że nie interesują mnie czynniki : to jest stałe dla wszystkich mnie obchodzi.
źródło
Add-Prefix-Set
czy zaczynasz od dowolnego zestawu łańcuchów?Add-Prefix-Set
wprowadzić)Odpowiedzi:
Myślałem od dłuższego czasu, ale nie znalazłem problemu z wykonaniem wszystkich operacji w najgłupszy możliwy sposób w strukturze DAG przypominającej trie:
Dodaj zestaw prefiksów
Łączyć
Połącz korzenie dwóch struktur: utwórz wszystkie węzły potomne drugiego korzenia potomnego pierwszego węzła. Możesz teraz mieć wiele krawędzi oznaczonych tym samym znakiem z tego samego węzła.
Leniwa aktualizacja katalogu głównego
Uzyskaj prefiksy
Leniwa aktualizacja katalogu głównego. Teraz znajdź wszystkie dzieci roota i zgłoś do nich zestaw liter na krawędziach.
Usuń prefiksy
Leniwa aktualizacja katalogu głównego. Zjednocz wszystkie dzieci roota i ustaw wskaźnik root na wynik tego połączenia. Leniwa aktualizacja nowego katalogu głównego.
Trwałość
źródło