马拉车算法

马拉车算法是一个字符串中求最长子字符串,并且此字符串是回文。
本质上是中心扩展法。只是避免有某些多余的计算
核心算法如图所示
马拉车算法
假设 已知在A点为中心的回文字符串长度为 E~C段,并且距离上 A-D == D-B
那么,如果我要求 B 点为中心的回文字符串长度,那它肯定等于 D点为中心的回文字符串长度啊。
是的,最核心的就这个了。
剩下的是解决回文字符串长度是奇数还是偶数(利用插入其它字符)
以及如何更新可利用的A点。


附poj 3974 AC代码

int mlc(string &str)
{
    if (str.size() == 0) return 0;
    string newStr;
    newStr.push_back('^');
    newStr.push_back('#');
    int len = str.size();
    for (int i = 0; i < len; i++)
    {
        newStr.push_back(str[i]);
        newStr.push_back('#');
    }
    newStr.push_back('$');
    int newLen = newStr.size();
    vector<int> v(newLen,0);
    int C = 0, R = 0;
    for (int i = 1; i < newLen - 1; i++)
    {
        int i_mirror = 2 * C - i;
        if (R > i)
        {
            v[i] = min(R - i, v[i_mirror]);
        }
        else
        {
            v[i] = 0;
        }
        while (newStr[i + 1 + v[i]] == newStr[i - 1 - v[i]])
        {
            ++v[i];
        }
        if (i + v[i] > R)
        {
            C = i;
            R = i + v[i];
        }
    }
    int ret = 1;
    for (int i = 1; i < newLen - 1; i++)
    {
        ret = max(ret, v[i]);
    }
    return ret;
}

int main()
{
    string str;
    int idx = 0;
    for (; ; )
    {
        cin >> str;
        if (str == "END")
        {
            break;
        }
        int len = mlc(str);
        cout << "Case " << ++idx << ": " << len << endl;
    }
    return 0;
}
上一篇:Java:关于“StringBuilder“的运用


下一篇:第四章 字符串的练习(1.5)