1.算法的思想##
看了一下一个老外的博客,他把kmp简单的过了一遍,非常简洁,貌似一下子看懂了不少。他的博客地址。
2.代码实现##
//
// main.cpp
// leetcode
//
// Created by YangKi on 15/11/12.
// Copyright © 2015年 YangKi. All rights reserved.
// 本版本的kmp找到第一个符合的子字符串就跳出返回结果
#include<cstdlib>
#include<iostream>
#include<vector>
#include<unordered_map>
using namespace std;
class Solution {
public:
int kmp( char * pattern, int l1, char* words, int l2 )
{
if (l1>l2) {
printf("can't find\n");
return -1;
}
int *next=new int[l1]; //跳跃数组
next[0]=0;
//1.根据pattern构造next数组
for (int i=1; i<l1; i++)//字长为1的不算前缀后缀,i指向当前长度的字符串的结尾
{
int j=(i+1)-1;
for(; j>=1; j--)//j为考察的前/后缀长度
{
if ( cmp(pattern, pattern+i-(j-1), j)==true ) {
next[i]=j;
break;
}
}
if(j==0) next[i]=0;
}
//for(int i=0; i<l1; i++)printf("%d ", next[i]);
//2.开始搜索子字符串,用next数组跳
for( int i=0; i<=l2-l1; )
{
int tempi=i;//用于对比,是大数组的指针
int partial_length=0;
for(int j=0; j<l1; j++, tempi++)
{
if(pattern[j] != words[tempi])
{
break;
}
else
{
partial_length++;
}
}
if(partial_length>1)
{
if(partial_length==l1)//找到了,本版本的kmp找到第一个符合的子字符串就跳出返回结果
{
printf("the first substring index is %d\n", i);
return i;
}
else//要借用next数组去跳
{
i+= ( partial_length - next[partial_length - 1] );
}
}
else//partial_length==0,1 都只跳一位
{
i++;
}
}
printf("can't find\n");
return -1;
}
private:
bool cmp(char* c1, char* c2, int length)
{
for (int i=0; i<length; i++)
{
if(c1[i] != c2[i]) return false;
}
return true;
}
};
int main()
{
Solution *s = new Solution();
char c1[8]={'a', 'b', 'a', 'b', 'a', 'b', 'c', 'a'};
char c2[20]={"ababababca"};
s->kmp(c1, 8, c2, 12);
return 0;
}