• 【字符串】【KMP模板--最小循环节总结】


    今天下午刚好看了一道最小循环节的题,感觉还是挺有意思的,不过自己还是看了一个下午才理解点,感觉自己好菜哎~~~

    kmp算法里的next数组还有一个性质就是j-next[j]是s2的最小循环节
    稍微修改下next数组的定义,这里是修改前的定义链接,我们不再要求s2[j]和s2[k]不同,我们仅需要去掉if语句,直接令s2[j] = k;修改后代码如下

    void getNext()
    {
        int k,j;
        k = -1;
        j = 0;
        next[j] = -1;
        while(s2[j] != '')
        {
            while(k != -1 &&s2[j] != s2[k])
                k = s2[k];
            next[++j] = ++k;//修改部分 
        }
        return ;
     } 

    需要注意几点:
    1:j-next[j]是最小循环节的长度
    2:字符串的循环条件是j%(j-next[j])==0&&next[j]!=0
    3:最小循环节的循环次数是j/(j-next[j])

    具体的程序运行过程如下面这张图,代码在末尾我输入的字符串ababa进行测试,如果看了图还不太清楚的小伙伴可以把代码拷下去自己运行一遍,大概就了解了,实在不清楚的话,可以手动推一遍(kmp手动模拟三遍的路过)

    最小循环节

    #include<stdio.h>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    char s1[1000];
    int next[1000];
    int l;
    void getNext(char s1[],int next[])
    {
        int i,j;
        j = -1;
        i = 0;
        next[i] = -1;
        while(s1[i]!='')
        {
            while(j!=-1&&s1[j]!=s1[i])
                j = next[j];
            i++;
            j++;
            next[i] = j;
        }
        return;
    }
    int main()
    {
        int t,i,ans;
    
        while(scanf("%s",s1)!=EOF)
        {
            getNext(s1,next);
            l = ans = strlen(s1);
            i = next[l];
            while(i != -1)
            {
                int k = l - i;//最小循环节 
                int p = l%k;//循环k节点若干次后剩余部分的长度
                int q = (k-p)%k;//q为字符串s1要想补齐成恰好整数个k所需要的最少字符数 
                if( l+q >= k*2)//判断循环是否超过两次
                    ans = min(ans,p);
                i = next[i];
            }
            printf("%d
    ",ans);//输出最小补全长度 
        }
        return 0;
    }
  • 相关阅读:
    C# 把类实例保存到文件里(类的序列化和反序列化)
    C# 枚举的初始化
    旋转 3d
    asp.net页面间传值方式
    sql获取当前时间
    SqlServer中循环和条件语句示例!
    SQL Server 代理(已禁用代理 XP)
    JQuery源码实现
    C#计算一段程序运行时间的三种方法
    java开发配套版本
  • 原文地址:https://www.cnblogs.com/hellocheng/p/7350066.html
Copyright © 2020-2023  润新知