BF算法与KMP算法
2018-01-28 18:00
211 查看
BF算法
两个字符串 str sub算法基本思想:
初始 i=0,j=0
1、当str[i]==sub[j]时i++,j++;
2、当str[i]!=sub[j]时,i=i-j+1,j=0;
3、当j>=strlen(str)或者i>=strlen(sub)结束
BF 算法的时间复杂度是:O(mn)
m 代表主串的长度, n 代表子串的长度。
代码实现:
int BF(const char *str, const char *sub, int pos) { int lenstr = strlen(str); int lensub = strlen(sub); if (pos < 0 || pos>lenstr) { return -1; } int i = pos; int j = 0; while (i < lenstr&&j < lensub) { if (str[i] == sub[j]) { i++; j++; } else { i = i - j + 1; j = 0; } } if (j >= lensub) { return i - j; } return -1; }
KMP算法
KMP 算法更为高效时间复杂度为 O(m+n)
m 代表主串的长度, n 代表子串的长度。
KMP 和 BF 唯一不一样的地方在:主串的 i 并不会回退, 并且 j 也不会移动到 0 号位置。
那j该如何退呢?
当 i 和 j 走到如下图位置
j 不需要回退到0,而是回退到上一个‘c‘的位置即可,假设每次回退为“K”位置。
我们要在确定sub中匹配到那一位不同时回退到对应的k位置,把所有的k都保存在next[strlen(sub)]数组中。
那如何确定每次回退到哪呢?
如上图i=j=5时,str[i]!=sub[j],(用P0表示str[0]的字符,用S0表示sub[0]的字符)所以可以保证
P0P1P2P3P4=S0S1S2S3S4
这是观察可得应把j回退到S2即可,由于S0S1==P3P4==S3S4
同理假设str[i]!=sub[j]
得
P0P1P2,,,,,Pi ==S0S1S2,,,,,Sj
回退到k
存在S0,,,Sk-1 == Pi-k,,,Pi-1==Sj-k,,,,,Sj-1
第j位不同时,回退到k位置
so, next[j] = k ————条件1
由于当0号下标不同时,我们就会让j回退到当前位置,
但是默认next[0]=-1———条件2
由于当1号下标不同时,我们就会让j回退到0号位置,
so,next[1]=0———条件3
我们要根据已知的三个条件求 next[2] next[3],,,,,,,直到求出所有的next数组
由于Sj 与 Sk只存在两种关系 1、Sj = Sk 2、Sj != Sk
根据这两种关系我们做出两种假设
假设1、Sj = Sk
这时
S0,,,Sk-1 == Pi-k,,,Pi-1==Sj-k,,,,,Sj-1 【1】就可以拓展为
S0,,,Sk-1Sk ==Sj-k,,,,,Sj-1Sj 【2】
由于在【1】==>next[j] = k
so, 【2】==>next[j+1]=k+1
假设2、Sj != Sk ,如下图S2!=S5
这时由多次观察总结得
S5本来按Sj==Sk,应该回退到2位置但是很明显,S2!=S5,这时让k继续回退到2的k值====>k=next[k]
如此,就能求得所有next数组的值
每次遇到不同,让j回退到next[j]
代码实现
void GetNext(char *sub,int *next) { int lensub = strlen(sub); next[0] = -1; next[1] = 0; int i = 2;//第二项 int k = 0; while (i < lensub) { if ((k == -1) || sub[k] == sub[i -1]) { next[i] = k + 1; i++; k++; } else { k = next[k]; } } } int KMP(char *str, char *sub, int pos) { int lenstr = strlen(str); int lensub = strlen(sub); if (pos < 0 || pos>lenstr) { return -1; } int i = pos; int j = 0; int *next = (int *)malloc(sizeof(int)*strlen(sub)); assert(next != NULL); GetNext(sub, next); while (i < lenstr &&j < lensub) { if ((j == -1) || str[i] == sub[j]) { i++; j++; } else { j = next[j]; } } if (j >= lensub) { return i - j; } return -1; }
4000
相关文章推荐
- 从BF算法到KMP算法(字符串匹配算法)
- 字符串的模式匹配详解--BF算法与KMP算法
- 嵌入式 KMP算法详解及各种应用和BF算法提及
- (八)实现了串比较里的BF算法和KMP算法
- c++实现BF算法 KMP算法
- 字符串模式匹配中BF算法和KMP算法的java实现
- BF算法 + KMP算法
- HDOJ--2087--剪花布条(BF算法和KMP算法都能使用)
- (五)串的模式匹配——BF算法和KMP算法
- BF算法与KMP算法
- 字符串查找KMP算法和BF算法
- BF算法和KMP算法对比
- BF算法和KMP算法(javascript版本)
- BF算法和KMP算法的简介
- [数据结构与算法]BF算法与KMP算法实现
- 串的模式匹配(BF算法,KMP算法)
- 字符串匹配算法--BF算法(暴力破解法)+KMP算法
- 串的模式匹配算法:BF算法与KMP算法
- 数据结构笔记--通过与BF算法的比较理解KMP算法
- BF算法和KMP算法