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


    题目:

    输入字符串中对称的子字符串的最大长度。比如输入字符串“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
  • 相关阅读:
    编码
    TCP
    Http
    信息安全
    https基本原理
    Android之ListView异步加载图片且仅显示可见子项中的图片
    android 一些数据转换方法
    Android 关于 OnScrollListener 事件顺序次数的简要分析
    图片的内存缓存控制
    Android实现图片宽度100%ImageView宽度且高度按比例自动伸缩
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4865013.html
Copyright © 2020-2023  润新知