看毛片(KMP)算法简析

来源:互联网 发布:若解多情网络结局 编辑:程序博客网 时间:2024/04/18 23:53

看毛片算法又称KMP算法。该算法之所以得名无外乎如下原因。

每当涉及该算法都甚新鲜,极想把玩一番,经过一番琢磨,终于悟透其本质。遂将其束之高阁,数月之后,再相邂逅,新鲜如初,又是一番把玩、醒悟、遗忘,如此循环以至无穷。足见,该算法与看毛片的道理一脉相承。初看新鲜刺激,观摩研究,醒悟不过如此而已。遂撇下而顾其它,数月之后,复习之,依然新鲜激动如故。以致数年。


KMP算法核心在于求匹配失败时模式串的后退数组,大多数都命名为next数组,感觉pre应该更符合直觉。假设在T[i] 和P[j]处失配,j必须是往回退的不可能在向前走。因此要求的后退数组应该这个样子:pre[sizeof(P)]

(1)

 T[i] 和P[j]处失配,则找到pre[j],假设pre[j]=k,意味着P有相同的前缀和后缀,且长度为k,此时在j处失配,自然要回退,退到哪?退到k处。

(2)

咋求pre[j+1]呢?要分两种情况,

       a) pre[j]=pre[k], 所以pre[j+1]=k+1=pre[j]+1,中间那个k+1难理解?要知道k是什么意思,k是P[0..j]的相同前缀和后缀长度,此时两个缀的后面各增加了一个相同的字符,所以pre[j+1]自然要在k的基础上+1了; 

       b)pre[j]!=pre[k],这就意味着pre[j+1]的相同前缀和后缀不能用pre[j]那一套了。此时,要有递归的思想了,要观察更早的前缀和后缀是否能满足pre[j]=pre[k],如果找到这个位置则可基于此求出pre[j+1]了。如果一直往前看,一直没发现满足要求的前缀和后缀,咋整?不咋整,说明P[0..j+1]不存在相同的前缀和后缀,此时如果T[i+1]和P[j+1]失配了,P就只能从头开始了。找不到在代码中这样表示pre[0]=-1。


上面基本就是看毛片算法的精髓。还是结合代码来理解吧。程序不会看会的,得写!

    int kmp(char *t, char *p) {         int tsize = strlen(t), psize = strlen(p), k=-1, j=0, i=0, *prev = new int[psize];         prev[0] = -1;                  while (j < psize-1)            if ( k == -1 || p[k] == p[j] ) prev[++j] = ++k;               else k = prev[k];                  i = j =0;         while (i < tsize && j < psize)            if (j == -1 || t[i] == p[j]) {i++;j++;}            else j = prev[j];                 if (j == psize) return i - j;        else  return -1;      }
求后退数组加模式匹配,世界上基本不会有比这更短的KMP了!



0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 挂水了还是有热度怎么办 陌陌工会不结算工资怎么办 滴滴给了差评怎么办 饿了么星级低怎么办 滴滴乘客给低星怎么办 蘑菇街自动收货前还没到怎么办 小主播人气太少别人看不到怎么办 税收分类编码不可用怎么办 斗鱼鱼翅充错了怎么办 苹果指纹摔坏了怎么办 小米5指纹坏了怎么办 苹果5s指纹失灵怎么办 学生赌博输了3万怎么办 电脑录屏没有声音怎么办 别人说你没有他美怎么办 没有你我怎么办歌词是什么意思 要是没有他我怎么办啊歌词 用喀秋莎保存的视频黑屏怎么办 电脑杀毒之后开不了机怎么办 夫妻离婚分房分车怎么办 请的护身符丢了怎么办 老车轻微烧机油怎么办 电脑下软件变卡怎么办 机械表日历偏了怎么办 子宫内膜异位痛经怎么办 凉着了坏肚子怎么办 昆虫叮咬后疼痛起水泡怎么办 每次来月经都痛经怎么办 人左肩的灯灭了怎么办 香港超过7天了怎么办? 手机拍完照图像是倒的怎么办 地下城金币邮寄卡了怎么办 wow7.3打团本卡怎么办 上古卷轴5出bug怎么办 苹果手机打游戏太卡怎么办 梦幻将军令换了怎么办 手机丢了将军令怎么办 大军之印放弃了怎么办 联想一体机进入界面就死机怎么办 nmd袜子鞋露脚趾怎么办 生意不顺意志崩溃了怎么办