首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >KMP前缀表

KMP前缀表
EN

Stack Overflow用户
提问于 2012-12-10 05:36:30
回答 6查看 35K关注 0票数 41

我正在阅读关于字符串匹配的KMP

它需要通过构建前缀表对模式进行预处理。

例如,对于字符串表,前缀ababaca是:P = [0, 0, 1, 2, 3, 0, 1]

但我不清楚这些数字表明了什么。我读到,当模式发生变化时,它有助于找到匹配的模式,但我无法将此信息与表中的数字联系起来。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-12-10 05:40:09

每个数字都属于相应的前缀("a","ab","aba",...)对于每个前缀,它表示与前缀匹配的该字符串的最长后缀的长度。我们在这里不把整个字符串算作后缀或前缀,它被称为自后缀和自前缀(至少在俄语中,对英语术语不确定)。

所以我们有字符串"ababaca“。让我们来看看它。KMP为每个非空的前缀计算前缀函数。让我们将s[i]定义为字符串,p[i]定义为前缀函数。前缀和后缀可以重叠。

代码语言:javascript
复制
+---+----------+-------+------------------------+
| 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                      |
|   |          |       |                        |
+---+----------+-------+------------------------+

计算字符串S的前缀函数的简单C++代码:

代码语言:javascript
复制
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;
}
票数 85
EN

Stack Overflow用户

发布于 2017-01-19 09:12:32

这段代码可能不是最短的,但很容易理解代码流。用于计算前缀数组的简单Java代码-

代码语言:javascript
复制
    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]);
    }

它产生所需的输出-

0 0 1 2 3 0 1

票数 6
EN

Stack Overflow用户

发布于 2019-10-11 17:42:49

Python实现

代码语言:javascript
复制
p='ababaca'

l1 = len(p)

j = 0
i = 1
prefix = [0]

while len(prefix) < l1:
    if p[j] == p[i]:
        prefix.append(j+1)
        i += 1
        j += 1
    else:
        if j == 0:
            prefix.append(0)
            i += 1
        if j != 0:
            j = prefix[j-1]

print prefix
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13792118

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档