Dwa ciągi długości k , różniące się jednym znakiem, dzielą prefiks długości l i sufiks długości m taki, że k = l + m + 1 .
Odpowiedź Simona Prinsa koduje to, przechowując wszystkie kombinacje prefiksów / sufiksów jawnie, tzn. abc
Staje się *bc
, a*c
i ab*
. To k = 3, l = 0,1,2 i m = 2,1,0.
Jak wskazuje valarMorghulis, możesz organizować słowa w drzewie prefiksów. Istnieje również bardzo podobne drzewo sufiksów. Dość łatwo jest rozszerzyć drzewo o liczbę węzłów liści poniżej każdego przedrostka lub przyrostka; można to zaktualizować w O (k) podczas wstawiania nowego słowa.
Powodem, dla którego chcesz, aby liczba rodzeństwa była liczona, jest to, aby wiedzieć, biorąc pod uwagę nowe słowo, czy chcesz wyliczyć wszystkie ciągi z tym samym przedrostkiem, czy też wyliczyć wszystkie ciągi z tym samym przyrostkiem. Np. Dla „abc” jako danych wejściowych możliwe prefiksy to „”, „a” i „ab”, podczas gdy odpowiednie sufiksy to „bc”, „c” i „”. Jak widać, w przypadku krótkich sufiksów lepiej wyliczyć rodzeństwo w drzewie prefiksów i odwrotnie.
Jak wskazuje @einpoklum, z pewnością możliwe jest, że wszystkie ciągi mają ten sam przedrostek k / 2 . To nie jest problem w tym podejściu; drzewo prefiksów będzie liniowe do głębokości k / 2, a każdy węzeł do głębokości k / 2 będzie przodkiem 100 000 węzłów liści. W rezultacie drzewo sufiksów będzie używane do głębokości (k / 2-1), co jest dobre, ponieważ ciągi znaków muszą różnić się sufiksami, ponieważ mają wspólne prefiksy.
[edytuj] Jako optymalizacja, po określeniu najkrótszego unikalnego prefiksu ciągu, wiesz, że jeśli istnieje jeden inny znak, musi to być ostatni znak prefiksu, a po znalezieniu prawie duplikatu sprawdzanie prefiksu, który był o jeden krótszy. Jeśli więc „abcde” ma najkrótszy unikalny przedrostek „abc”, oznacza to, że istnieją inne ciągi zaczynające się od „ab?” ale nie z „abc”. Tj. Gdyby różniły się tylko jedną postacią, byłaby to trzecia postać. Nie musisz już sprawdzać „abc? E”.
Zgodnie z tą samą logiką, jeśli okaże się, że „cde” jest unikalnym najkrótszym sufiksem, to wiesz, że musisz sprawdzić tylko przedrostek o długości 2 „ab”, a nie przedrostek o długości 1 lub 3.
Zauważ, że ta metoda działa tylko dla dokładnie jednej różnicy między znakami i nie uogólnia do 2 różnic między znakami, polega na tym, że jeden jeden znak jest oddzieleniem identycznych przedrostków i identycznych przyrostków.