马拉车算法(解决最长回文串)

一:返回最长回文串的字符个数

	#include<iostream>
	#include<cstdio>
	# include<string.h> 
	using namespace std;
	const int maxn = 100010;
	char ma[maxn << 1],s[maxn];
	int mp[maxn << 1];
	void Manacher(char s[],int len)
	{
	    int l = 0;
	    ma[l++] = '$';
	    ma[l++] = '#';
	    for(int i = 0;i < len; i++)
	    {
	        ma[l++] = s[i];
	        ma[l++] = '#';
	    }
	    ma[l] = 0;
	    /*i代表此刻字符串的位置
	     * id代表此时最大回文子串的中心
	     * mx代表当前得到的最大回文子串的右边界*/
	    int mx = 0;
	    int id = 0;
	    for(int i = 0;i < l; i++)
	    {
	        mp[i] = mx > i ? min(mp[id * 2 - 1],mx - i) : 1;
	        while(ma[i + mp[i]] == ma[i - mp[i]])
	            mp[i]++;
	        if(i + mp[i] > mx)
	        {
	            mx = i + mp[i];
	            id = i;
	        }
	    }
	}
	int main()
	{
	    while(scanf("%s",s) == 1)
	    {
	        int len = strlen(s);
	        Manacher(s,len);
	        int ans = 0;
	        for(int i = 0;i < 2 * len + 2; i++)
	            ans = max(ans,mp[i] - 1);
	        printf("%d\n",ans);
	    }
	}

二:返回最长回文串
还有用后缀数组解决最长回文串的问题:文章第五题

	#include <iostream>
	#include <string>
	#include <cstring>
	 
	using namespace std;
	 
	void findBMstr(string str0){
	    string str;
	    str += "$#";
	    int n=str0.size();
	    for(int i = 0; i < n; i++){
	        str += str0[i];
	        str += "#";
	    }
	    int len=str.size();
	    int *p = new int[len + 1];
	    memset(p, 0, sizeof(p));
	    int mx = 0, id = 0;
	    for(int i = 1; i <=  len; i++){
	        if(mx > i){
	            p[i] = (p[2*id - i] < (mx - i) ? p[2*id - i] : (mx - i));
	        }
	        else{
	            p[i] = 1;
	        }
	        while(str[i - p[i]] == str[i + p[i]])
	            p[i]++;
	        if(i + p[i] > mx){
	            mx = i + p[i];
	            id = i;
	        }
	    }
	    int Max = 0, ii;
	    for(int i = 1; i < len; i++){
	        if(p[i] > Max){
	            ii = i;
	            Max = p[i];
	        }
	    }
	    Max--;
	    int s = ii - Max ;
	    int e = ii + Max;
	    for(int i = s; i <= e; i++){
	        if(str[i] != '#'){
	            cout << str[i];
	        }
	    }
	    cout << endl;
	    delete  p;
	}
	int main()
	{
	    string str;
	    cin>>str;
	    findBMstr(str);
	    return 0;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值