解释不对的地方 希望帮忙指出来我们一起探讨
1.kmp算法的原理:
本部分内容转自:
http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html
2.next数组 即是找搜索词在 k属于[0,搜索词长-1] 位置时 前缀与后缀的最长公共子串(连续)
例如 :字符串 “ABCDAB”的前缀为[A, AB, ABC, ABCD, ABCDA,],后缀为[BCDAB, CDAB, DAB, AB, B],”AB”作为他们的最长公共子串 长度为2 。
*前缀起点相对稳定 后缀起点不断变化****
void create_next(string str2 , int *next )
{
// ############Create next##################
unsigned int i = 0;
unsigned int j = 1;
next[0] = 0;
while(j < str2.size())
{
if(str2[i] == str2[j])
{
i++;
next[j] = i;//如果先j++就会跳过比较的那个字符str2[j]
j++;
}
else
{
i=next[i];//i会一步一步回退
j++;
}
}
}
3.判断字符串是否匹配: i 为源字符串下标 j 为搜索词字符串下标
(1)如果str1[i] != str2[j] 则下标 j 需要回退 (如果一直不相等 就会根据next数组一直回退 直到回退到0)
(2)如果相等 那么 j++
(3)如果j = str2.size() 代表已经越界了 而str1还没有退出 则匹配完毕
(1)(2)(3)的每一步 i 都需要向后移动
bool is_str_exist(string str1 , string str2 ,int *next)
{
for(int i = 0 , j = 0 ; i < str1.size() ; i++)//控制字符串源
{
while(j > 0 && str1[i] != str2[j])
j = next[j-1]; //一步一步根据next数组往回跳
if(str1[i] == str2[j])
{
j++;
}
if(j == str2.size())//如果j已经越界了
{
return 1;
}
}
return 0;
}
**********完整程序**********
#include <iostream>
#include <string>
#include <vector>
using namespace std;
bool isstrexist(string str1 , string str2)
{
// ############Create next###################
vector<int>next(str2.size(),0);//
unsigned int i = 0;
unsigned int j = 1;
next[0] = 0;
while(j < str2.size())
{
if(str2[i] == str2[j])
{
i++;
next[j] = i;//如果先j++就会跳过比较的那个字符str2[j]
j++;
}
else
{
i=next[i];//i回一步一步回退
j++;
}
}
for(auto i : next)
cout<<i<<" ";
cout<<endl;
//####################test exist########################
for(int i = 0 , j = 0 ; i < str1.size() ; i++)//控制字符串源
{
while(j > 0 && str1[i] != str2[j])
j = next[j-1]; //一步一步根据next数组往回跳
if(str1[i] == str2[j])
{
j++;
}
if(j == str2.size())//如果j已经越界了
{
return 1;
}
}
return 0;
}
int main()
{
string str1 = "BBCABCDABABCD ABCDABDE";
string str2 = "ABCDA";
if(isstrexist(str1,str2))
cout<<"exist"<<endl;
cout<<str2<<endl;
return 0;
}
谢谢