Manacher's algorithm (algorithm to find longest palindrome substring in linear time)

前端 未结 10 490
走了就别回头了
走了就别回头了 2020-12-22 16:02

After spending about 6-8 hours trying to digest the Manacher\'s algorithm, I am ready to throw in the towel. But before I do, here is one last shot in the dark: can anyone e

10条回答
  •  隐瞒了意图╮
    2020-12-22 16:38

    using namespace std;
    
    class Palindrome{
    public:
        Palindrome(string st){
            s = st; 
            longest = 0; 
            maxDist = 0;
            //ascii: 126(~) - 32 (space) = 94 
            // for 'a' to 'z': vector> v(26,vector(0)); 
            vector> v(94,vector(0)); //all ascii 
            mDist.clear();
            vPos = v; 
            bDebug = true;
        };
    
        string s;
        string sPrev;    //previous char
        int longest;     //longest palindrome size
        string sLongest; //longest palindrome found so far
        int maxDist;     //max distance been checked 
        bool bDebug;
    
        void findLongestPal();
        int checkIfAnchor(int iChar, int &i);
        void checkDist(int iChar, int i);
    
        //store char positions in s pos[0] : 'a'... pos[25] : 'z' 
        //       0123456
        // i.e. "axzebca" vPos[0][0]=0  (1st. position of 'a'), vPos[0][1]=6 (2nd pos. of 'a'), 
        //                vPos[25][0]=2 (1st. pos. of 'z').  
        vector> vPos;
    
        // 
        //   i.e.  abccba  anchor = 3: position of 2nd 'c', dist = 3 
        //   looking if next char has a dist. of 3 from previous one 
        //   i.e.  abcxcba anchor = 4: position of 2nd 'c', dist = 4 
        map mDist;
    };
    
    //check if current char can be an anchor, if so return next distance to check (3 or 4)
    // i.e. "abcdc" 2nd 'c' is anchor for sub-palindrome "cdc" distance = 4 if next char is 'b'
    //      "abcdd: 2nd 'd' is anchor for sub-palindrome "dd"  distance = 3 if next char is 'c'
    int Palindrome::checkIfAnchor(int iChar, int &i){
        if (bDebug)
              cout<<"checkIfAnchor. i:"< 2
        if ( iSize == 0 || vPos[iChar][iSize - 1] < (i - 2)){
            if (bDebug)
                  cout<<"       .This cannot be an anchor! i:"<first<<" . dist:"<second<second == iDist;  //check here, because it can be updated in 1st. if
            if (bDiffDist){
                if (bDebug)
                    cout<<"       .Distance checked! :"<second += 2; //update next distance to check
                    if (it->second > maxDist) {
                         if (bDebug)
                              cout<<"       .previous MaxDist:"<second;
                         if (bDebug)
                              cout<<"       .new MaxDist:"<second > i2ndMaxDist) {//check this...hmtest
                         i2ndMaxDist = it->second;
                         if (bDebug)
                              cout<<"       .second MaxDist:"<second != iDist)
                    cout<<"       .Dist diff. Anchor:"<first<<" dist:"<second<<" iDist:"<second > iDist){
                    if (iSize > 1) {
                       if (bDebug)
                           cout<<"       . < Dist . looking further..."< 0 && vPos[iChar][iSize - 1] == 0){
                    iStart = 0;
                    iCurrLength = i+1;
                }
                //last char in string
                else if (b1stOrLastCharInString && i == (s.size() - 1)){
                    iStart = i - it->second; 
                    iCurrLength = it->second + 1;
                }
                else {
                    iStart = i - it->second + 1; 
                    iCurrLength = it->second - 1;  //"xabay" anchor:2nd. 'a'. Dist from 'y' to 'x':4. length 'aba':3
                }
    
                if (iCurrLength > longest){
                    if (bDebug)
                          cout<<"       .previous Longest!:"<first<<" dist:"<second< 0){ 
            if (bDebug)
                  cout<<"       .new maxDist needed";
            if (i2ndMaxDist > 0) {
                maxDist = i2ndMaxDist;
                if (bDebug)
                  cout<<"       .assigned 2nd. max Dist to max Dist"<second > maxDist)
                        maxDist = it->second;
                }
                if (bDebug)
                  cout<<"       .new max dist assigned:"< 'z'))
        while (j < n && (s[j] < ' ' && s[j] > '~'))
            j++;
        if (j > 0){
            s.substr(j);
            n = s.length();
        }
        // for 'a' to 'z' change size of vector from 94 to 26 : int iChar = s[0] - 'a';
        int iChar = s[0] - ' ';
        //store char position
        vPos[iChar].push_back(0);  
    
        for (int i = 1; i < n; i++){
            if (bDebug)
                cout<<"findLongestPal. i:"< 25){
            if (iChar < 0 || iChar > 94){
                if (bDebug)
                    cout<<"       . i:"< (iDist - 2)){
                //if this is the longest palindrome! 
                if (longest < (iDist - 1)){
                    sLongest = s.substr((i - iDist + 2),(iDist - 1));
                }
            }
        }
    };
    
    int main(){
        string s;
        cin >> s;
    
        Palindrome p(s);
        p.findLongestPal();
        cout<

提交回复
热议问题