在字符串尾部添加字符,使之变成回文串

 

 

 

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
//最长回文,Manacher算法
char s[211000], c[111000];//注意S数组的大小至少要开C数组的两倍
int p[211000];//P可以理解为回文字符串的半径

void init()//初始化S数组
{
    int i, j;
    s[0] = '@';
    for (i = 0; c[i] != 0; i++)
    {
        s[2 * i + 1] = '#';
        s[2 * i + 2] = c[i];
    }
    s[2 * i + 1] = '#';
    s[2 * i + 2] = 0;
}
void manacher()
{
    int id = 0, mx = 0;
    int maxLen = 0, start = 0;
    for (int i = 1; s[i] != 0; i++)
    {
        if (mx > i)
            p[i] = min(p[2 * id - i], mx - i);
        else
            p[i] = 1;
        //p[i]=mx>i?min(p[2*id-i],mx-i):1;
        while (s[i + p[i]] == s[i - p[i]])
            p[i]++;
        if (i + p[i] > mx)
        {
            mx = i + p[i];
            id = i;
        }
        
    }
    mx = 0;
    for (int i = 1; s[i] != 0; i++)
    {
        if (p[i] > mx)
        {
            mx = p[i];
            start = (i - p[i]) / 2;
            maxLen = mx - 1;//mx-1是回文子串的长度,start是回文子串的起始位置
        }
    }
    //cout << start << " " << start + maxLen-1 << endl;
    //找到最长回文子串的起始地址start、和回文串的长度maxlen后,剩余部分,直接反序添加
    string temp1 = "", temp2 = "";
    if (maxLen == strlen(c))//本身就是回文串
    {
        cout << c << endl;
    }
    else if (start + maxLen-1 == strlen(c) - 1)
    {
        for (int i = start - 1; i >= 0; i--)
            temp1 = temp1 + c[i];
        cout << c << temp1 << endl;
    }
    else//如果回文子串不在尾部,只能整体翻转拼接在尾部才是回文串
    {
        for (int i = strlen(c) - 1; i >= 0; i--)
            temp2 = temp2 + c[i];

        cout << c << temp2 << endl;
    }
}
int main()//用cin\cout 会超时
{
    while (~scanf("%s", c))
    {
        init();
        manacher();
    }
    return 0;
}

 

posted @ 2020-08-09 09:49  知道了呀~  阅读(2218)  评论(0编辑  收藏  举报