c++ 獲取字符串中最長的回文子串


 

#include <vector>
#include <iostream>
#include <string>
using namespace std;
string Manacher(string s) {

    // 插入特殊符號“#”
    string t = "$#";
    for (int i = 0; i < s.size(); ++i) {
        t += s[i];
        t += "#";
    }

    // 初始化變量
    vector<int> p(t.size(), 0);
    int mx = 0, id = 0, resLen = 0, resCenter = 0;

    //循環t.size()-1次
    for (int i = 1; i < t.size(); ++i) {

        // p[i]:表示以 t[i] 字符為中心的回文子串的半徑
        // i < mx 的含義:證明 i 在 當前id 對應子回文串的范圍之內
        p[i] = i<mx ? min(p[2 * id - i], mx - i) : 1;

        //從字符串中點向兩端擴展,直到不能再擴展
        while (t[i + p[i]] == t[i - p[i]]){
            ++p[i];
        }

        //mx:當前已經處理的回文子串所達最靠后的終點
        //id:終點最靠后的回文子串的中心字符下標
        if (mx < i + p[i]) {
            mx = i + p[i];
            id = i;
        }

        //結果
        //回文字符串最大長度reslen
        //回文字符串的中心位置resCenter
        if (resLen < p[i]) {
            resLen = p[i];
            resCenter = i;
        }
    }

    //例子: "noon",中間的 '#' 在字符串 "$#n#o#o#n#" 中的位置是5,半徑也是5,
    //字符串的長度(半徑減一):4,起始位置(中間位置減去半徑再除以2):0

    //結論:最長子串的長度是半徑resLen減1,起始位置是中間位置resCenter減去半徑resLen再除以2。
    return s.substr((resCenter - resLen) / 2, resLen - 1);
}

//主程序
int main() {
    string s = "aawaw";
    cout << Manacher(s) << endl;
}

 

 

參考:

https://www.jianshu.com/p/c82cada7e5b0
https://www.cnblogs.com/grandyang/p/4475985.html
https://www.jianshu.com/p/7dacc9a3c9a0

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM