leetcode686. 重复叠加字符串匹配---kmp讲解

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;
}

 

    原文作者:KMP算法
    原文地址: https://blog.csdn.net/m0_37561165/article/details/81066188
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞