[ACM]KMP算法的两种写法,从0开始,从1开始

KMP算法

KMP理论学习链接

算法模板(从1开始)


char p[maxn],s[maxm];   ///p为模板数组,s为原数组
int ne[maxn];           ///next数组 

int n,m;///n为模板

void get_next()
{
    for (int i = 2, j = 0; i <= n; i ++ ){
        while (j && p[i] != p[j + 1])   j = ne[j];
        if (p[i] == p[j + 1])   j ++ ;
        ne[i] = j;
    }
}

void KMP()
{
    for (int i = 1, j = 0; i <= m; i ++ ){
        /// while中: j是变为0了,在模板串中退无可退了,s[i] != p[j + 1]是匹配到不相同的位置了
        while (j && s[i] != p[j + 1])   j = ne[j];
        if (s[i] == p[j + 1])   j ++ ;
        if (j == n){
            // 匹配成功后的逻辑
			j = ne[j];///注意!!!这里等于0,和等于ne[i] 匹配成功后回跳还是不回跳会对结果有影响
        }
    }
    
}

/// s[]是长文本,p[]是模式串,n是s的长度,m是p的长度
//求模式串的Next数组:
int main()
{
    cin >> n >> p + 1 >> m >> s + 1;
    
	get_next();
    KMP();
    
    return 0;
}

算法模板(从0开始)


void get_next(string p)
{
    int len = p.length();

    int i = 0, j = -1 ;
    ne[0] = -1;
    while(i < len)
    {
        if(~j && p[i] != p[j])  j = ne[j];
        else    ne[++i] = ++j;
    }
}


bool kmp(string p)
{
    get_next(p);
    int i =0,j=0,len = s.length(),le = p.length();;

    while(i < len )
    {
        if( ~j && s[i] != p[j] )    j = ne[j];
        else    i++,j++;
        if(j >= le){
            ///
        }
    }
}
原文地址:https://www.cnblogs.com/hoppz/p/14785421.html