2010-09-30 10 views
3

Comment trouver le plus long préfixe de palindrome d'une chaîne dans O (n)?Le plus long préfixe palindrome

+3

Cela ressemble à une question de devoirs. Si c'est le cas, il devrait être étiqueté comme tel. –

+1

Définit le préfixe de palindrome le plus long. Et le temps devrait-il être lié par O (n) ou la mémoire aussi? Et est ce devoir? –

+1

Je pense que cette réponse est un toyota –

Répondre

1

Solution pour un problème plus général, le préfixe mais pas sous-chaîne, en O (n):

http://www.akalin.cx/2007/11/28/finding-the-longest-palindromic-substring-in-linear-time/

second résultat sur Google pour "le plus long préfixe palindrome" ....

Ou

solution en utilisant le suffixe arbres:

http://www.allisons.org/ll/AlgDS/Tree/Suffix/

+0

A la fonction 'fastLongestPalindromes (..)' sur le lien vers akalin.cx effectivement 'O (n)' pire cas complexité? Je vois deux boucles imbriquées .. –

+0

N'ont pas tout lu mais 2 boucles imbriquées ne signifie pas complexité quadratique. La continuation au début de la fonction doit s'assurer que la boucle interne n'est exécutée que dans quelques cas et que la complexité globale de chaque exécution de cette boucle est O (n). –

5

Utilisez un rolling hash. Si a est votre chaîne, laissez ha[x] être le hachage des premiers caractères x dans a calculé de gauche à droite et laissez hr[x] être le hachage des premiers caractères x dans s calculé de droite à gauche. Vous êtes intéressé par la dernière position i pour laquelle hf[i] = hb[i].

code en C (utiliser deux hash pour chaque direction afin d'éviter les faux positifs):

int match = n - 1; 

int ha1 = 0, ha2 = 0, hr1 = 0, hr2 = 0; 
int m1 = 1, m2 = 1; 
for (int i = 0; a[i]; ++i) 
{ 
    ha1 = (ha1 + m1*a[i]) % mod1; 
    ha2 = (ha2 + m2*a[i]) % mod2; 

    hr1 = (a[i] + base1*hr1) % mod1; 
    hr2 = (a[i] + base2*hr2) % mod2; 

    m1 *= base1, m1 %= mod1; 
    m2 *= base2, m2 %= mod2; 

    if (ha1 == hr1 && ha2 == hr2) 
     match = i; 
} 
+0

Je pense que la partie 'de droite à gauche' n'est pas présente dans l'exemple de code ... ('i' va de gauche à droite et vous accédez seulement' a [i] '. –

+0

@Andre Holzner -' Je vais seulement de gauche à droite: à chaque pas de 'i', vous aurez la longueur du préfixe palindromique actuel le plus long stocké dans' match', c'est seulement les hashs qui roulent dans les deux sens – IVlad

+0

+1, je n'ai pas Je sais que ça s'appelait 'rolling hash', mais même deux hashes ne garantissent pas que chaque positif soit 'vrai' (sans parler de ces coefficients inhabituels :)). Simplement parce que pour une certaine longueur _n_ il y a plus de chaînes de caractères n que de paires différentes de nombres entiers _ (ha1, ha2) _. Et si vous faites la vérification de chaque positif, vous obtenez O (n^2) sur une chaîne uniforme ('aaaaaaaa ...'). –

Questions connexes