web-dev-qa-db-fra.com

Table des préfixes KMP

Je lis environ KMP pour la correspondance de chaîne.
Il a besoin d'un prétraitement du modèle en créant une table de préfixes.
Par exemple pour la chaîne ababaca la table des préfixes est: P = [0, 0, 1, 2, 3, 0, 1]
Mais je ne suis pas clair sur ce que montrent les chiffres. J'ai lu que cela aide à trouver des correspondances du modèle quand il change mais je ne peux pas connecter cette information avec les nombres dans le tableau.

33
Cratylus

Chaque numéro appartient au préfixe correspondant ("a", "ab", "aba", ...) et pour chaque préfixe il représente la longueur du suffixe le plus long de cette chaîne qui correspond au préfixe. Nous ne comptons pas ici la chaîne entière comme suffixe ou préfixe, cela s'appelle auto-suffixe et auto-préfixe (au moins en russe, pas sûr des termes anglais).

Nous avons donc la chaîne "ababaca". Regardons ça. KMP calcule la fonction de préfixe pour chaque préfixe non vide. Définissons s[i] comme chaîne, p[i] comme fonction de préfixe. le préfixe et le suffixe peuvent se chevaucher.

+---+----------+-------+------------------------+
| i |  s[0:i]  | p[i]  | Matching Prefix/Suffix |
+---+----------+-------+------------------------+
| 0 | a        |     0 |                        |
| 1 | ab       |     0 |                        |
| 2 | aba      |     1 | a                      |
| 3 | abab     |     2 | ab                     |
| 4 | ababa    |     3 | aba                    |
| 5 | ababac   |     0 |                        |
| 6 | ababaca  |     1 | a                      |
|   |          |       |                        |
+---+----------+-------+------------------------+

Code C++ simple qui calcule la fonction Prefix de la chaîne S:

vector<int> prefixFunction(string s) {
    vector<int> p(s.size());
    int j = 0;
    for (int i = 1; i < (int)s.size(); i++) {
        while (j > 0 && s[j] != s[i])
            j = p[j-1];

        if (s[j] == s[i])
            j++;
        p[i] = j;
    }   
    return p;
}
74
imslavko

Ce code n'est peut-être pas le flux de code le plus court, mais facile à comprendre. Simple Java Code pour calculer le préfixe-Array-

    String pattern = "ababaca";
    int i = 1, j = 0;
    int[] prefixArray = new int[pattern.length];
    while (i < pattern.length) {

        while (pattern.charAt(i) != pattern.charAt(j) && j > 0) {
            j = prefixArray[j - 1];

        }
        if (pattern.charAt(i) == pattern.charAt(j)) {
            prefixArray[i] = j + 1;
            i++;
            j++;

        } else {
            prefixArray[i] = j;
            i++;
        }
    }

    for (int k = 0; k < prefixArray.length; ++k) {
        System.out.println(prefixArray[k]);
    }

Il produit la sortie requise

0 0 1 2 3 0 1

3
Yogesh Sanchihar

texte de chaîne = "ababbabbababbababbabb"; statique int arr [30];

int i = 1;
while (i < text.length())
{
    int j = 0;
    int value = 0;
    while (((i + j) < text.length()) && (text[j] == text[i + j]))
        val[i + j] = ++value, j++;
    i += j + 1;
}

sortie requise stockée dans val []

0
MOHAMED SABTHAR