字符串可以通过bf和kmp方法查找
bf 时间复杂度是O(n*m) 子串从头查找与串中原来与自己匹配的项如果匹配 就继续查找 如果 失配(不匹配)则返回到i(第一个匹配的字符)下一个(大概如下图)
优点 简单 缺点 时间复杂度比较大
代码如下
int BF(const char *str,const char *sub,int pos)//O(n*m)
{
if(pos < 0)
{
return -1;
}
int lenstr = strlen(str);
int lensub = strlen(sub);
int i = pos;
int j = 0;
while(i<lenstr && j<lensub)
{
if(str[i] == sub[j])
{
i++;
j++;
}
else
{
i = i-j+1;//失配,退到i原来的位置的下一个
j = 0;
}
}
if(j >= lensub)//找到了
{
return i-j;
}
else
{
return -1;
}
}
KMP 优点:时间复杂度比较小O(n+m)缺点:比较复杂
要先知道子串的k和j k==j k和j是相等长度相等字符的两个字符串k从头开始找 j从子串失配前开始找
找k和j大概如下图
算法sub[j]==sub[k(j从1 开始j+1《lenstr k从0开始)]|| k=-1 k=k+1 继续
else k=next【k】继续
代码如下
static void GetNext(const char*sub,int *next)
{
int lensub = strlen(sub);
next[0] = -1;
next[1] = 0;
int j = 1;//通过j求j+1的值
int k = 0;
while(j+1<lensub)
{
if(k==-1 || sub[j]==sub[k])
{
next[++j] = ++k;//next[j]=k;++j;++k;
}
else
{
k = next[k];//
}
}
}
//KMP 算法特点:i不回退,时间复杂度O(n+m)
int KMP(const char *str,const char *sub,int pos)//O(n+m)
{
if(pos < 0)
{
return -1;
}
int lenstr = strlen(str);
int lensub = strlen(sub);
int i = pos;
int j = 0;
int *next = (int *)malloc(lensub*sizeof(int));
GetNext(sub,next);
while(i<lenstr && j<lensub)
{
if(j==-1 || (str[i]==sub[j]))
{
i++;
j++;
}
else//i不回退,j退到next[j](即k位置)
{
j = next[j];
}
}
free(next);
if(j >= lensub)//找到了
{
return i-j;
}
else
{
return -1;
}
}
KMP 获取next【i】(即k值)str[i]==sub[j])继续
else 子串的j退回之前k的位置 再继续