使用kmp算法查找子串

问题:在字符串S中查找Sub

边界条件:S长度或者Sub长度为0,或者Sub长度大于S长度,返回-1;

KMP算法

失效函数f(i)

假如目标串是Sub,则失效函数f(i)表示既是Sub(0,i)的真前缀又是Sub(0,i)的后缀的最长串的长度,通俗地说就是前后相等的子串长度。

有时候也被叫做next数组,因为它代表了如果匹配失败下一次将从哪个开始匹配

举一个书本中的例子,求ababaa的失效函数。

失效函数自变量 子串 首尾相等的子串 失效函数值
0 a 0
1 ab 0
2 aba a 1
3 abab ab 2
4 ababa aba 3
5 ababaa a 1

当使用编程语言实现时,求值思想是在上一个失效函数值的基础上求出当前所求的失效值。这个是我从编译原理第二版上看到的方法,比较简洁明了。继续使用上面的例子,对ababaa求失效函数,根据定义我们可以直接得出f(0) 为0。

在求其他位置的效值的过程中,我们维护两个下标:一个是当前位置的下标,一个上一个位置的失效值。

为什么要保存这两个下标呢?

1.我们通过当前位置下标取得要比较的字符,并将失效值写入对应的地方。

2.通过观察可以发现,假如上一个位置的失效函数值为i,当前位置为j,那么在i和j之前的字符都已经被对比且为相等了,如果i和j对比不相等,直接把i变成i-1处的失效函数值,假设是q,那么q和j之前的字符也肯定是比对且为相等的了,这就是失效函数的神奇之处。

文字描述不容易理解,下面通过画图来描述

image

用c++实现


vector<int> next(const string & S )
{
    vector<int> f(S.length());  //已经知道需要求的值的个数
    int i = 0;
    f[0]= 0; //第一个肯定是0
    for (int j = 1; j < S.length(); j++) {
        while (i > 0 & S[i] != S[j]) i = f[i-1];  //如果当前要对比的字符还是不相等且没回退到第一个则一直回退到前一个的失效函数值处
        if (S[i] == S[j]) {
            ++ i;
            f[j] = i;
        }else {
            f[j]= 0;
        }
    }
    return f;
}

使用求得的失效函数

使用KMP算法求子串位置,查找到则返回-1.
在前面的求失效函数的过程中我们已经利用了失效函数了,如果没理解可以多看几遍,这个地方有点绕。原理是当对比到第j个字符发现不相等时,前面的j-1个字符其实已经是相等的了,接下来要做的就是利用这一部分信息来避免回溯。

对比发现不相等的情况以及处理

书中使用的术语是“滑动”,效果如图


根据上一位置失效值移动

将上述思想使用c++表达,未做错误处理,因为这篇文章的目的是理清思路。

int index (const string & S,const string &B)
{
    vector<int> f = next(B);
    int i = 0;
    for (int j = 0; j < S.length(); j++) {
            while (i > 0 && B[i] != S[j]) i = f[i-1];
            if (S[j] == B[i]) 
            if (j == B.length()) return j;
    }   
    return -1;

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342