牛客竞赛--字符串的问题(KMP)

题目地址

字符串的问题

解题思路

求出Next数组后,将Next数组 [1, len) 所有数字进行标记,如果Next[len]可以找到标记说明字符串中间还出现过一次长度为Next[len]的字符串,否则让len = Next[len],去查看字符串开头长度为Next[len]的字串有没有循环节,有的话就是答案了。如果没有,那就是没有满足题意得,输出题目要求输出的。

比如 abcabchahabcabc,Next[len] = 6, 但是标记数组里面vis[6] = 0,因此需要 len = Next[len] = 6,回到字符串第六个位置,然后看看这段里有没有循环节,如果这段有循环节,很显然后面也一定有,因为两个子串是相等的。当找到循环节后就是答案了。

AC代码

#include 
#include 
 
using namespace std;
 
int Next[1000006], vis[1000006];
 
void GetNext(string &s)
{
    int k = -1, j = 0, len = s.size();
    Next[0] = -1;
     
    while (j < len)
    {
        if (k == -1 || s[j] == s[k])
        {
            k++;
            j++;
            Next[j] = k;
        }
        else
        {
            k = Next[k];
        }
    }
}
 
int main()
{
    string s;
     
    cin >> s;
     
    int len = s.size();
     
    GetNext(s);
     
    for (int i=1; i<len; i++)
        vis[Next[i]] = 1;
         
    int x = Next[len];
     
    while (x != -1 && !vis[x])
    {
        x = Next[x];
    }
     
    if (x == 0 || x == -1)
        cout << "Just a legend" << endl;
    else
    {
        for (int i=0; i<x; i++)
        {
            cout << s[i];
        }
         
        cout << endl;
    }
     
    return 0;
}

你可能感兴趣的:(练习题)