KMP算法
KMP算法解决的是字符串匹配的问题 文本串:aabaabaaf 模式串:aabaaf 判断文本串中是否存在模式串 需要用到前缀表: 前缀:包含首字母不包含尾字母的所有子串 后缀:包含为字母不包含首字母的所有子串 求最长相等前后缀 初始化 处理前后缀不相同的情况 处理前后缀相同的情况 更新next数组 i:指向后缀末尾位置 j:指向前缀末尾位置,还代表i包括i之前子串的最长相等前后缀长度 初始化:j=0;注意这个位置对j的初始化其实有好几种方式,有的人习惯于赋值-1,也就是对整个next数组进行-1操作;有的习惯于使用原next数组,我比较倾向于next原数组,这二者的差别只在于进行j回溯的时候那句逻辑。 next[0]=0; ?然后循环里对i进行初始化,循环里头,先判断后缀不相同的情况:不相同的话要对j进行回溯,回溯到前一位对应的回退位置; 如果前后缀相同,将j++,然后更新next数组。 这样就完成了next数组的构建。 然后进行匹配的时候,两个字符串用两个下标分别进行迭代,注意模式串的下标初始值跟next数组起始位置一样,习惯于初始化为0,这也是我为什么倾向于next数组初始化为0的原因; 还是先处理不匹配的情况,进行回溯; 匹配的话移动; 根据不同题目判读不同终止条件。 class Solution { public: void getNext(int* next,const string& s) { int j = 0;//前缀的末尾,统一0操作,所以初始化为0 next[0] = j; for(int i = 1; i < s.size(); i++) { 先处理前后缀不相等的情况,如果不相等,前缀要进行回退,知道回退到相等或者到模式串开头位置,回退的下标就是当前前缀前一个位置的next数组的值 while(j > 0 && s[i] != s[j]) { j = next[j-1]; } 处理前后缀相同的情况,如果相同,i和j都往后移一位,j++,next[i]等于j if(s[i] == s[j]) { j++; } next[i] = j; } } int strStr(string haystack,1)">string needle) { haystack是文本串 needle是模式串 KMP算法,需要构造next数组 if(needle.size() == 0) { return ; } int next[needle.size()]; getNext(next,needle);得到前缀表 得到前缀表之后,需要进行匹配,用j来迭代模式串,用i来迭代文本串 因为next数组里是从0开始的 0; i < haystack.size(); i++先处理二者不相等的情况,如果不相等,模式串需要回退,按照next数组进行回退 0 && haystack[i] != needle[j]) { j = next[j-]; } 如果二者相等,继续向后判断 if(haystack[i] == needle[j]) { j++;i++在循环里头 } 判断是不是模式串在文本串里头的条件:迭代器j已经到了尾部 if(j == needle.size()) { return i - needle.size() + ; } } return -; } }; ? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |