https://blog.csdn.net/v_july_v/article/details/7041827#t10
KMP:
假设现在我们面临这样一个问题:有一个文本串S,和一个模式串P, 假设现在我们面临这样一个问题:有一个文本串S,和一个模式串P,现在要查找P在S中的位置,怎么查找呢?
文本串S“BBC ABCDAB ABCDABCDABDE”,和模式串P“ABCDABD”。
#include <iostream>
using namespace std;
void GetNext(char* p,int next[])
{
int pLen = strlen(p);
next[0] = -1;
int k = -1;
int j = 0;
while (j < pLen - 1)
{
//p[k]表示前缀,p[j]表示后缀
if (k == -1 || p[j] == p[k])
{
++k;
++j;
next[j] = k;
}
else
{
k = next[k];
}
}
}
int KmpSearch(char* s, char* p,int next[])
{
int i = 0;
int j = 0;
int sLen = strlen(s);
int pLen = strlen(p);
while (i < sLen && j < pLen)
{
//①如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++
if (j == -1 || s[i] == p[j])
{
i++;
j++;
}
else
{
//②如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]
//next[j]即为j所对应的next值
j = next[j];
}
}
if (j == pLen)
return i - j;
else
return -1;
}
int main()
{
char *p="abcdabd";
char *s="bbc abcdab abcdabcdabde";
int a=strlen(p);
int *next=new int[a] ();
GetNext(p,next);
int res=KmpSearch(s,p,next);
cout<<res<<endl;
return 0;
}
leetcode686题目:
给定两个字符串 A 和 B, 寻找重复叠加字符串A的最小次数,使得字符串B成为叠加后的字符串A的子串,如果不存在则返回 -1。
举个例子,A = “abcd”,B = “cdabcdab”。
答案为 3, 因为 A 重复叠加三遍后为 “abcdabcdabcd”,此时 B 是其子串;A 重复叠加两遍后为”abcdabcd”,B 并不是其子串。
注意:
A
与 B
字符串的长度在1和10000区间范围内。
思路:
先直接找,找不到再重复之后再找,然后再重复再找。。。
kmp用上了。
代码:
调了半天发现老是超时,原来这道题根本就不用
class Solution {
public:
void GetNext(char* p,int next[])
{
int pLen = strlen(p);
next[0] = -1;
int k = -1;
int j = 0;
while (j < pLen - 1)
{
//p[k]表示前缀,p[j]表示后缀
if (k == -1 || p[j] == p[k])
{
++k;
++j;
next[j] = k;
}
else
{
k = next[k];
}
}
}
int KmpSearch(char* s, char* p,int next[])
{
int i = 0;
int j = 0;
int sLen = strlen(s);
int pLen = strlen(p);
while (i < sLen && j < pLen)
{
//①如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++
if (j == -1 || s[i] == p[j])
{
i++;
j++;
}
else
{
//②如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]
//next[j]即为j所对应的next值
j = next[j];
}
}
if (j == pLen)
return i - j;
else
return -1;
}
int repeatedStringMatch(string A, string B) {
char *s=new char[100000]();
char p[10002]={0};
//strncpy(p,A.c_str(),A.size());
strncpy(p,B.c_str(),B.size());
string Atmp(A);
int lenA=A.size();
int lenB=B.size();
int multiple=lenB/lenA;
int kk=1;
/*for(kk=1;kk<=multiple;kk++)
{
A+=Atmp;
}*/
while(A.size()<B.size())
{
A+=Atmp;
kk++;
}
strncpy(s,A.c_str(),A.size());
int a=strlen(p);
int *next=new int[a] ();
GetNext(p,next);
int res=KmpSearch(s,p,next);
if(res!=-1){
/*if(A.size()==B.size())
return kk;*/
return kk;
}
else{
strncpy(s,A.c_str(),A.size());
a=strlen(p);
next=new int[a];
GetNext(p,next);
res=KmpSearch(s,p,next);
if(res!=-1)
return kk+1;
else
return -1;
}
return -1;
}
};
其实直接用str.find就好了。。。尴尬
哎。。
#include <iostream>
#include <string>
#include <string.h>
using namespace std;
void GetNext(char* p,int next[])
{
int pLen = strlen(p);
next[0] = -1;
int k = -1;
int j = 0;
while (j < pLen - 1)
{
//p[k]表示前缀,p[j]表示后缀
if (k == -1 || p[j] == p[k])
{
++k;
++j;
next[j] = k;
}
else
{
k = next[k];
}
}
}
int KmpSearch(char* s, char* p,int next[])
{
int i = 0;
int j = 0;
int sLen = strlen(s);
int pLen = strlen(p);
while (i < sLen && j < pLen)
{
//①如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++
if (j == -1 || s[i] == p[j])
{
i++;
j++;
}
else
{
//②如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]
//next[j]即为j所对应的next值
j = next[j];
}
}
if (j == pLen)
return i - j;
else
return -1;
}
int main()
{/*"abcabcabcabc"
"abac""abcd"
"cdabcdab"*/
/*"bcacbcbbbbbbbacbcaacbccaa"
"bbcacbcbbbbbbbacbcaacbccaacbcacbcbbbbbbbacbcaacbccaaabcacbcbbbbbbbacbcaacbccaacbcacbcbbbbbbbacbcaacbccaabbcacbcbbbbbbbacbcaacbccaacbcacbcbbbbbbbacbcaacbccaabbcacbcbbbbbbbacbcaacbccaabbcacbcbbbbbbbacbcaacbccaabbcacbcbbbbbbbacbcaacbccaabbcacbcbbbbbbbacbcaacbccaabbcacbcbbbbbbbacbcaacbccaabbcacbcbbbbbbbacbcaacbccaabbcacbcbbbbbbbacbcaacbccaaabcacbcbbbbbbbacbcaacbccaacbcacbcbbbbbbbacbcaacbccaabbcacbcbbbbbbbacbcaacbccaacbcacbcbbbbbbbacbcaacbccaaabcacbcbbbbbbbacbcaacbccaaabcacbcbbbbbbbacbcaacbccaacbcacbcbbbbbbbacbcaacbccaabbcacbcbbbbbbbacbcaacbccaacbcacbcbbbbbbbacbcaacbccaacbcacbcbbbbbbbacbcaacbccaaabcacbcbbbbbbbacbcaacbccaaa"*/
/*"abababaaba"
"aabaaba"*/
string A("abcd");
string B("cdabcdab");
char *s=new char[1000000]();
char p[10000]={0};
//strncpy(p,A.c_str(),A.size());
strncpy(p,B.c_str(),B.size());
string Atmp(A);
int lenA=A.size();
int lenB=B.size();
int multiple=lenB/lenA;
int kk=1;
while(A.size()<B.size())
{
A+=Atmp;
kk++;
}
strncpy(s,A.c_str(),A.size());
int a=strlen(p);
int *next=new int[a] ();
GetNext(p,next);
int res=KmpSearch(s,p,next);
if(res!=-1){
cout<<kk<<endl;
return 0;
}
else{
A+=Atmp;
strncpy(s,A.c_str(),A.size());
a=strlen(p);
next=new int[a] ();
GetNext(p,next);
res=KmpSearch(s,p,next);
if(res!=-1){
cout<<kk+1<<endl;
return 0;
}
else{
cout<<-1<<endl;
return -1;
}
}
cout<<-1<<endl;
return 0;
}