(算法-字符串)最长对称子串

题目:

输入字符串中对称的子字符串的最大长度。比如输入字符串“roorle”,由于该字符串里最长的对称子字符串是“roor”,因此输出4.

思路:

1、求字符串”roorle“和反序”elroor“的最长公共子串

2、最长回文子串

代码:

1、最长公共子串

《(算法-字符串)最长对称子串》
《(算法-字符串)最长对称子串》

#include<iostream>

using namespace std;

// naive method
// O(n^3)
int comlen(const string &str1,int i,int m,const string &str2,int j,int n){
    int len=0;
    while(i<m && j<n && str1[i++]==str2[j++])
        len++;
    return len;
}

int LongestCommonSubString(const string &str1,const string &str2){
    int m=str1.size();
    int n=str2.size();
    int maxLen=0;
    int maxIndex=-1;

    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            int len=comlen(str1,i,m,str2,j,n);
            if(len>maxLen){
                maxLen=len;
                maxIndex=i;
            }
        }
    }

    for(int i=0;i<maxLen;i++){
        cout<< str1[maxIndex+i] <<" ";
    }
    cout<<endl;

    return maxLen;
}


// DP method
// O(n^2)
int LongestCommonSubString_1(const string &str1,const string &str2){
    int m=str1.size();
    int n=str2.size();

    int dp[m][n];
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++)
            dp[i][j]=0;
    }

    int maxLen=0;
    int maxIndex;
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            if(str1[i]==str2[j]){
                if(i>0 && j>0)
                    dp[i][j]=dp[i-1][j-1]+1;
                else
                    dp[i][j]=1;
            }
            if(dp[i][j]>maxLen){
                maxLen=dp[i][j];
                maxIndex=i-maxLen+1;
            }
        }
    }

    for(int i=0;i<maxLen;i++)
        cout<<str1[maxIndex+i]<<" ";
    cout<<endl;

    return maxLen;
}


// DP method
// O(n^2)
int LongestCommonSubString_2(const string &str1,const string &str2){
    int m=str1.size();
    int n=str2.size();

    int dp[m][n];
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++)
            dp[i][j]=0;
    }

    int maxLen=0;
    int maxIndex;
    for(int i=m-1;i>=0;i--){
        for(int j=n-1;j>=0;j--){
            if(str1[i]==str2[j]){
                if(i<m-1 && j<n-1)
                    dp[i][j]=dp[i+1][j+1]+1;
                else
                    dp[i][j]=1;
            }
            if(dp[i][j]>maxLen){
                maxLen=dp[i][j];
                maxIndex=i;
            }
        }
    }

    for(int i=0;i<maxLen;i++)
        cout<<str1[maxIndex+i]<<" ";
    cout<<endl;

    return maxLen;
}


// DP method
// O(n^2)
int LongestCommonSubString_3(const string &str1,const string &str2){
    int m=str1.size();
    int n=str2.size();

    int dp[m+1][n+1];
    for(int i=0;i<=m;i++){
        for(int j=0;j<=n;j++)
            dp[i][j]=0;
    }

    int maxLen=0;
    int maxIndex;
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            if(str1[i]==str1[j])
                dp[i][j]=dp[i-1][j-1]+1;

            if(dp[i][j]>maxLen){
                maxLen=dp[i][j];
                maxIndex=i-maxLen+1;
            }
        }
    }

    for(int i=0;i<maxLen;i++)
        cout<<str1[maxIndex+i]<<" ";
    cout<<endl;

    return maxLen;
}

int main(){
    string str1="abcdefg";
    string str2="bgfcdft";
    cout<<LongestCommonSubString(str1,str2)<<endl;
    cout<<LongestCommonSubString_1(str1,str2)<<endl;
    cout<<LongestCommonSubString_2(str1,str2)<<endl;
    cout<<LongestCommonSubString_3(str1,str2)<<endl;
    return 0;        
}

View Code

2、最长回文子串

《(算法-字符串)最长对称子串》
《(算法-字符串)最长对称子串》

#include<iostream>
using namespace std;

// brute force
string findLongestPalindrome_1(const string &str){
    int length=str.size();
    int maxLength=0;
    int start;

    for(int i=0;i<length;i++){
        for(int j=i+1;j<length;j++){
            int left,right;
            for(left=i,right=j;left<right;left++,right--){
                if(str[left]!=str[right])
                    break;
            }
            if(left>=right && (j-i)>maxLength){
                maxLength=j-i+1;
                start=i;
            }
        }
    }

    if(maxLength>0)
        return str.substr(start,maxLength);
    return NULL;
}


// dynamic programming
string findLongestPalindrome_2(string &str){
    const int length=str.size();
    int maxLength=1;
    int start;

    bool dp[length][length];

    for(int i=0;i<length;i++)
        for(int j=0;j<length;j++)
            dp[i][j]=false;

    for(int i=0;i<length;i++){
        dp[i][i]=true;
        if(i<length-1 && str[i]==str[i+1]){
            dp[i][i+1]=true;
            start=i;
            maxLength=2;
        }
    }

    for(int len=3;len<=length;len++){
        for(int i=0;i<=length-len;i++){
            int j=i+len-1;
            if(dp[i+1][j-1] && str[i]==str[j]){
                dp[i][j]=true;
                start=i;
                maxLength=len;
            }
        }
    }

    if(maxLength>=2)
        return str.substr(start,maxLength);
    return NULL;
}

// pivot expand
string findLongestPalindrome_3(string &str){
    const int length=str.size();
    int maxLength=1;
    int start;
    
    // length is odd
    for(int i=0;i<length;i++){
        int left=i-1;
        int right=i+1;
        while(left>=0 && right<=length-1 && str[left]==str[right]){
            if(right-left+1>maxLength){
                start=left;
                maxLength=right-left+1;
            }
            left--;
            right++;
        }
    }

    // length is even
    for(int i=0;i<length;i++){
        int left=i;
        int right=i+1;
        while(left>=0 && right<=length-1 && str[left]==str[right]){
            if(right-left+1>maxLength){
                start=left;
                maxLength=right-left+1;
            }
            left--;
            right++;
        }
    }

    if(maxLength>0)
        return str.substr(start,maxLength);
    return NULL;
}


int main(){
    string str="ababcddcbbd";
    cout<<findLongestPalindrome_1(str)<<endl;
    cout<<findLongestPalindrome_2(str)<<endl;
    cout<<findLongestPalindrome_3(str)<<endl;
    return 0;
}

View Code

 

    原文作者:AndyJee
    原文地址: https://www.cnblogs.com/AndyJee/p/4865013.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞