2018年牛客多校算法寒假训练营练习比赛(第五场)C-字符串的问题(KMP or find)

题目链接:https://ac.nowcoder.com/acm/contest/77/C

思路:根据next 数组各值的含义:代表当前字符之前的字符串中,有多大长度的相同前缀后缀。例如如果next [j] = k,代表j 之前的字符串中有最大长度为k 的相同前缀后缀。我们用num数组存一下去除去开头和结尾的子串的最长前后缀的长度出现的次数。如果存在次数>=1直接输出,否则k = Next[k]继续寻找。找不到就输出Just a legend。

#include 
using namespace std;
const int maxn = 1e6+7;
int Next[maxn], num[maxn];
string p; int plen;
void getNext()
{
    int j, k; plen = p.length();
    j = 0; k = -1; Next[0] = -1;
    while(j < plen)
    {
    	 if(k == -1 || p[j] == p[k])
        {
        	++j; ++k;
            Next[j] = k;
        }
        else k = Next[k];
    }
}
int main()
{
    cin >> p; getNext();
    for(int i = 2; i < plen-1; i++) num[Next[i]]++;
    int k = Next[plen];
    while(k)
    {
        if(num[k])
        {
            for(int i = 0; i < k; i++)
                cout << p[i];
            return 0;
        }
        k = Next[k];
    }
    puts("Just a legend");
}

思路二:利用string的find函数(find函数原理好像也是kmp)直接查找模拟。

#include 
using namespace std;
string s;
string pre, suf, mid, ans = "Just a legend";
int main()
{
    cin >> s;
    int len = s.size(), k = 0;
    while (++k < len)
    {
        pre = s.substr(0, k);
        suf = s.substr(len-k, k);
        if(pre == suf)
        {
            mid = s.substr(1, len-2);
            if(mid.find(pre) < len-1) ans = pre;
        }
    }
    cout << ans << endl;
}

 

你可能感兴趣的:(【模拟】)