| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1526 人关注过本帖
标题:请高手解释一下KMP算法。(如何实现字符串匹配)
只看楼主 加入收藏
xub615516015
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2008-8-23
收藏
 问题点数:0 回复次数:3 
请高手解释一下KMP算法。(如何实现字符串匹配)
请高手解释一下KMP算法。(如何实现字符串匹配)
搜索更多相关主题的帖子: problem KMP 
2008-08-23 15:24
blueboy82006
Rank: 5Rank: 5
来 自:幻想世界
等 级:贵宾
威 望:16
帖 子:1227
专家分:57
注 册:2007-7-23
收藏
得分:0 
KMP算法是一种用于字符串匹配的算法,这个算法的高效之处在于当在某个位置匹配不成功的时候可以根据之前的匹配结果从模式字符串的另一个位置开始,而不必从头开始匹配字符串.
因此这个算法的关键在于,当某个位置的匹配不成功的时候,应该从模式字符串的哪一个位置开始新的比较.假设这个值存放在一个next数组中,其中next数组中的元素满足这个条件:next[j] = k,表示的是当模式字符串中的第j + 1个(这里是遵守标准C语言中数组元素从0开始的约定,以下不再说明)发生匹配不成功的情况时,应该从模式字符串的第k + 1个字符开始新的匹配.如果已经得到了模式字符串的next数组,那么KMP算法的实现如下:
int i, j;
        for (i = pos, j = 0; i < S->length && j < T->length; )
        {
                // i是主串游标,j是模式串游标
                if (-1 == j ||                                // 模式串游标已经回退到第一个位置
                        S->str[i] == T->str[j]) // 当前字符匹配成功
                {
                        // 满足以上两种情况时两个游标都要向前进一步
                        ++i;
                        ++j;
                }
                else                                                //  匹配不成功,模式串游标回退到当前字符的next值
                {
                        j = next[j];
                }
        }

        if (j >= T->length)
        {
                // 匹配成功
                return i - T->length;
        }
        else
        {
                // 匹配不成功
                return -1;
        }

2008-08-23 15:40
blueboy82006
Rank: 5Rank: 5
来 自:幻想世界
等 级:贵宾
威 望:16
帖 子:1227
专家分:57
注 册:2007-7-23
收藏
得分:0 
下面看看如何得到next数组.
这是一个递推求解的过程,初始的情况是next[0] = -1.
假设在某一个时刻有如下的等式成立:str[0...k-1] = str[j - k...j - 1],那么next[j] = k,在这个前提下,继续进行下一个字符的匹配.
1)如果str[0...k] = str[j - k...j],那么next[j + 1] = next[j] + 1 = k + 1.
2)反之,如果上面的匹配不成立,那么就要从next[k]开始进行新的匹配,如果成功的话,那么:
next[j + 1] = next[next[j]] + 1 = next[k] + 1;
如果还是不能匹配成功就再从next[next[k]]的位置开始进行的新的匹配,直到匹配成功为止.如果这个过程一直进行下去都没有找到可以成功匹配的字符的话,那么next[j + 1] = 0,这时表示要从字符串的第一个位置开始新的匹配了.
用一个公式表示上述的算法,那么可以写作:
next[j] =
1)-1,当j = 0时;
2) Max{k | 0 <= k < j && str[0..k - 1] = str[j - k...j - 1]};
3)0,其他情况,此时匹配要从第一个位置重新开始.
寻找next数组的算法如下:

2008-08-23 15:41
blueboy82006
Rank: 5Rank: 5
来 自:幻想世界
等 级:贵宾
威 望:16
帖 子:1227
专家分:57
注 册:2007-7-23
收藏
得分:0 
// 第一个字符的next值是-1,因为C中的数组是从0开始的
        next[0] = -1;
        for (int i = 0, j = -1; i < pstr->length - 1; )
        {
                // i是主串的游标,j是模式串的游标
                // 这里的主串和模式串都是同一个字符串
                if (-1 == j ||                                                // 如果模式串游标已经回退到第一个字符
                        pstr->str[i] == pstr->str[j])        // 如果匹配成功
                {
                        // 两个游标都向前走一步
                        ++i;
                        ++j;
                        // 存放当前的next值为此时模式串的游标值
                        next[i] = j;
                }
                else                                                                // 匹配不成功j就回退到上一个next值
                {
                        j = next[j];
                }
        }

2008-08-23 15:41
快速回复:请高手解释一下KMP算法。(如何实现字符串匹配)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015318 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved