1 条题解

  • 0
    @ 2025-5-4 14:49:36

    分析:

    该代码运用了 KMP(Knuth-Morris-Pratt)算法,这是一种字符串匹配算法,主要用于高效地在主字符串中查找子字符串的出现位置。在本题中,KMP 算法的核心部分 next 数组(代码中为 nextt)被用于解决找出字符串所有既是前缀又是后缀的子串长度的问题。

    解题思路

    要找出给定字符串中所有既是前缀又是后缀的子串长度,可利用 KMP 算法中的 next 数组。next 数组记录了字符串中每个位置之前的子串的最长公共前后缀长度。通过不断回溯 next 数组的值,就能找出所有满足条件的子串长度。

    解题原理

    1.next 数组的构建:KMP 算法的核心在于构建 next 数组。next[i] 表示字符串中前 i+1 个字符组成的子串的最长公共前后缀长度。在构建 next 数组时,使用两个指针 i 和 k,i 用于遍历字符串,k 用于记录当前的最长公共前后缀长度。当 p[k] 与 p[i] 相等时,k 加 1;当不相等时,k 回溯到 next[k - 1] 的位置继续比较,直到 k 为 0 或者找到相等的字符。

    2.找出所有公共前后缀长度:在构建好 next 数组后,从 next[len - 1] 开始回溯,不断将 next[k - 1] 的值添加到结果数组中,直到 k 为 0。最后,将字符串的总长度 len 也添加到结果数组中,因为整个字符串本身也是一个既是前缀又是后缀的子串。

    实现步骤

    1.输入处理:使用 while 循环不断读取输入的字符串,直到文件结束。

    2.构建 next 数组:调用 makenextt 函数,传入字符串和其长度,构建 next 数组。

    3.找出所有公共前后缀长度:从 next[len - 1] 开始回溯,将 next[k - 1] 的值依次添加到结果数组 ans 中,直到 k 为 0。

    4.添加字符串总长度:将字符串的总长度 len 添加到结果数组 ans 中。

    5.排序并输出结果:对结果数组 ans 进行排序,然后按升序输出所有既是前缀又是后缀的子串长度。

    c++代码:

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    const int N=400005;
    int nextt[N];
    char str[N];
    int ans[N];
    void makenextt(char p[],int len)
    {
        nextt[0]=0;
        for(int i=1,k=0;i<len;i++)
        {
            nextt[0]=0;
            while(k>0&&p[k]!=p[i])
                k=nextt[k-1];
            if(p[k]==p[i])
                k++;
            nextt[i]=k;
        }
    }
    int main()
    {
        while(scanf("%s",str)!=EOF)
        {
            int len=strlen(str);
            makenextt(str,len);
            int k=nextt[len-1];
            int tot=0;
            while(k)
            {
                ans[++tot]=k;
                k=nextt[k-1];
     
            }
            ans[++tot]=len;
            sort(ans+1,ans+tot+1);
            printf("%d",ans[1]);
            for(int i=2;i<=tot;i++)
                printf(" %d",ans[i]);
            printf("\n");
        }
        return 0;
    }
    
    • 1

    信息

    ID
    1752
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    3
    已通过
    1
    上传者