web-dev-qa-db-fra.com

Le plus long palindrome d'une chaîne utilisant un arbre de suffixe

J'essayais de trouver le plus long palindrome d'une chaîne. La solution de force brute prend O (n ^ 3) temps. J'ai lu qu'il existait un algorithme temporel linéaire utilisant des arbres de suffixes. Je connais bien les arbres suffixés et je suis à l'aise pour les construire. Comment utilisez-vous l'arbre de suffixe construit pour trouver le plus long palindrome?.

45
shreyasva

Je crois que vous devez procéder de cette façon:

Soit y1y2 ... yn être votre chaîne (où y _je sont des lettres).

Créer l’arbre de suffixe généralisé de Sf = y1y2 ... yn$ et Sr = ynyn - 1 ... y1# (inversez les lettres et choisissez des caractères de fin différents pour Sf ($) et Sr } _ (#)) ... où Sf signifie "String, Forward" et Sr signifie "String, Reverse".

Pour chaque suffixe i dans Sf _, trouver l’ancêtre commun le plus bas portant le suffixe n - i + 1 dans Sr .

Ce qui va de la racine jusqu'à cet ancêtre commun le plus bas est un palindrome, parce que maintenant l'ancêtre commun le plus bas représente le préfixe commun le plus long de ces deux suffixes. Rappeler que:

(1) Un préfixe d'un suffixe est un sous-chaîne.

(2) Un (palindrome) est une chaîne identique à son inverse.

(3) Ainsi, le plus long palindrome contenu dans une chaîne est exactement la plus longue sous-chaîne commune de cette chaîne et son inverse.

(4) Ainsi, le plus long palindrome contenu dans une chaîne est exactement le plus long commun préfixe de toutes les paires de suffixes entre une chaîne et son inverse. C'est ce que nous faisons ici.

EXEMPLE

Prenons la Parole banane.

Sf = banane $

Sr = ananab #

Ci-dessous l’arborescence du suffixe généralisé de Sf _ et Sr }, où le nombre à la fin de chaque chemin est l’index du suffixe correspondant. Il y a une petite erreur, le a commun aux trois branches du parent de Blue_4 devrait se trouver sur son bord entrant, à côté de n

enter image description here

Le nœud intérieur le plus bas de l'arborescence est la plus longue sous-chaîne commune de cette chaîne et son inverse. En regardant tous les nœuds intérieurs de l'arbre, vous trouverez donc le plus long palindrome.

Le palindrome le plus long se trouve entre Green_0 et Blue_1 (c'est-à-dire banane et anana) et est anana


MODIFIER

Je viens de trouver ce document qui répond à cette question.

26
Ricky Bobby

Quelques années de retard ...

Supposons que s soit la chaîne d'origine et que r soit s inversé. Supposons également que nous ayons complètement construit un arbre de suffixes ST en utilisant s.

Notre prochaine étape consiste à vérifier tous les suffixes de r par ST. Avec chaque nouveau suffixe de r, nous allons conserver le nombre des premiers k que nous avons mis en correspondance avec un suffixe préexistant de l’arborescence (c’est-à-dire l’un des suffixes de s).

Par exemple, supposons que nous apparions le suffixe "RAT" de r, et que s contienne des suffixes commençant par "RA", mais aucun ne correspondant à "RAT". k équivaudrait à 2 lorsque nous devions finalement abandonner tout espoir pour les caractères finaux "T". Nous avons comparé les deux premiers caractères du suffixe de r avec les deux premiers caractères du suffixe de s. Nous appellerons ce noeud que nous avons atteint n.

Maintenant, comment savons-nous quand nous avons trouvé un palindrome?En cochant tous les noeuds feuille sous n.

Dans une arborescence de suffixes traditionnelle, l'index de départ de chaque suffixe est stocké au noeud feuille de cette branche de suffixe. Dans notre exemple ci-dessus, s peut avoir contenu un groupe de suffixes commençant par "RA", chacun commençant par l'un des index présents dans les descendants de noeud feuille de n.

Utilisons ces indices.

Qu'est-ce que cela signifie si nous faisons correspondre les caractères k de l'une des sous-chaînes de R avec les caractères k dans ST? Cela signifie simplement que nous avons trouvé une chaîne inversée. Mais qu'est-ce que cela signifie si l'emplacement où la sous-chaîne commence dans R est égal à la sous-chaîne correspondante dans S plus k? Oui, cela signifie que s[i] through s[i+k] se lit comme s[i+k] through s[i]! Et donc, soyez la définition, nous avons localisé un palindrome de taille k

Maintenant, tout ce que vous avez à faire est de garder un onglet sur le plus long palindrome trouvé à ce jour et de le retourner à la fin de votre fonction.

5
sgarza62

Explication simple et brève de Skiena - The Algorithm Design Manual

Trouver le plus long palindrome de S [à l'aide de l'arbre de suffixe] - A palindrome est une chaîne qui lit la même chose si l'ordre des caractères est inversé, tel que madam . Pour trouver le plus long palindrome dans une chaîne S, créez un arbre de suffixe contenant tous les suffixes de S et l'inversion de S, chaque feuille étant identifiée par sa position de départ. Un palindrome est défini par tout nœud de cet arbre qui a des enfants en avant et en arrière à partir de la même position.

0
Zsolt Safrany