• Manacher算法


    Manacher算法的应用

    求出字符串的最长回文子串。

    Manacher算法的流程

    1、插入特殊字符

    因为回文串的长度可能是奇数或偶数,为了不考虑这么多情况,就插入一些特殊字符。
    比如:abcddcba
    插入后变成:#a#b#c#d#d#c#b#a#
    所以可以将问题转化成求长度为奇数的回文串。

    2、求出每一位为中心的最长回文子串

    pip_i为以i为中心的最长回文子串。
    如何求pip_i
    通过前面的信息,首先要求出Maxright和pos。
    Maxright为前面所求的回文字符串中最靠右的右端点,pos为Maxright所对应的中心点。
    分两种情况讨论:

    1. i在Maxright的左边。先找到i关于pos的对应点j(j=2posij=2*pos-i)。如果将j的回文串复制到i,保证的回文长度为min(p[j],Maxrighti)min (p[j],Maxright-i),在这个基础上尽量往两边扩展。
    2. 否则,保证的回文长度为1,在这个基础上往两边扩展。
      然后更新Maxright和pos。

    3、统计答案

    例题

    Palindrome

    using namespace std;
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    char str[1000003];
    char s[2000007];
    int p[2000007];
    int main()
    {
    	ios::sync_with_stdio(0);
    	cin.tie(0);
    	cout.tie(0);
    	int T=1;
    	for (cin>>str;str[0]!='E';++T,cin>>str)
    	{
    		int len=1;
    		s[0]='#';
    		for (char* ch=str;*ch;++ch)
    		{
    			s[len++]=*ch;
    			s[len++]='#';
    		}
    		p[0]=1;
    		int pos=0,Maxright=0,ans=0;
    		for (int i=1;i<len;++i)
    		{
    			if (i<Maxright)
    				p[i]=min(p[(pos<<1)-i],Maxright-i);
    			else
    				p[i]=1;
    			int j,k;
    			for (j=i-p[i],k=i+p[i];j>=0 && k<len && s[j]==s[k];--j,++k);
    			p[i]=k-i;
    			if (k-1>Maxright)
    			{
    				Maxright=k-1;
    				pos=i;
    			}
    			ans=max(ans,p[i]-1);
    		}
    		cout<<"Case "<<T<<": "<<ans<<'
    ';
    	}
    	return 0;
    }
    
  • 相关阅读:
    Tensorflow io demo (待)
    tf.Dataset
    tf.estimator
    并发队列
    Callable的Future模式
    hadoop之HDFS介绍
    线程池
    并发工具类
    并发编程
    初学hadoop之hadoop集群搭建
  • 原文地址:https://www.cnblogs.com/jz-597/p/11145289.html
Copyright © 2020-2023  润新知