kmp 字串

https://ac.nowcoder.com/acm/problem/13253在这里插入图片描述
思路
因为我们只要保证所给t是s的字串,即kmp模板;
我们的重点是求s,t中最大的进制,最有可能使得t是s的字串,所以s要抓缓存最大的进制。

#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
string s,t;
int nex[1000010],n;
char p='0',to[16]={'0','1','2','3','4','5','6',
                    '7','8','9','A','B','C','D','E','F'};      //用来查找t的最大和s的进制转换
void change()
{
    int num=0;
    for(int i=0;i<16;i++)
    {
        if(to[i]==p)
        {
            num=i+1;          //进制要+1
            break;
        }
    }
    int tem;
    for(int i=1;i<=n;i++)
    {
        string now;
        tem=i;
        while(tem)        //逆序求出进制
        {
            now+=to[tem%num];
            tem/=num;
        }
        reverse(now.begin(),now.end());
        s+=now;
    }
}
void get_next()
{
    int j=0,k=-1;
    nex[0]=-1;
    int len=t.length();
    
    while(j<len)
    {
        if(p<t[j])p=t[j];
        if(k==-1||t[k]==t[j])
        {
            k++,j++;
            if(t[k]==t[j])
                nex[j]=nex[k];
            else nex[j]=k;
        }
        else 
            k=nex[k];
    }
    if(p>'F'||p<'0'||(p>'9'&&p<'A'))puts("no");
    else
        change();
}
int kmp()
{
    int j=0,k=0;
    int lens=s.length(),lent=t.length();
    while(j<lens&&k<lent)
    {
        if(k==-1||s[j]==t[k])
        {
            k++,j++;
        }
        else
            k=nex[k];
    }
    if(k==lent)printf("yes");
    else printf("no");
}
int main()
{
    scanf("%d",&n);
    cin>>t;
    get_next();
    kmp();
}

在这里插入图片描述

#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
string s;
int nex[1000010],num[1000010];
void get_next()
{
    int j=0,k=-1;
    nex[0]=-1;
    int len=s.length();
    while(j<len)
    {
        if(k==-1||s[k]==s[j])
        {
            k++,j++;
            nex[j]=k;
        }
        else 
            k=nex[k];
    }
}
int main()
{
    cin>>s;
    get_next();
    int len=s.length();
    for(int i=2;i<len;i++)         //为什么遍历nex数组查找与nex[len]相同的个数的数字呢?
    	num[nex[i]]++;             //因为可能字符串全是aaaaaaaaa,这样就找不到
    int k=nex[len];                 //统计每个nex的数据
    while(k)
    {
    	if(num[k])                 //存在与后缀相等的
    	{
    		for(int i=0;i<k;i++)
    			cout << s[i];
    		return 0;
		}
		k=nex[k];             //回溯,针对aaaa这种情况
	}
    puts("Just a legend");
}
发布了88 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44879687/article/details/102886852
kmp