當前位置: 首頁>>算法&結構>>正文


DP求最大回文子串長度

問題:給定字符串,求其最長回文子串的長度。回文串是形如”aba”, “abba”的對稱字符串。例如:字符串“xabcbam”的最長回文字符串長度為5。

這個問題可以用動態規劃(DP)來求解,其初始狀態和轉移方程如下:

gif.latex-8實現的代碼如下:


#include <stdio.h>
#include <string.h>

#define N 1024  //字符串最大長度
#define max(a, b) ((a) > (b) ? (a) : (b))

int g_cnt[N][N];  // g_cnt[i][j]表示i~j子串中最大回文長度, 默認全部初始化為0

//動態規劃求最長回文子串的長度
int dp_maxlen(const char *s){
    int slen = strlen(s);
    if(slen >= N){
        fprintf(stderr, "exceed size:%d\n", N);
        return -1;
    }
    
    //長度為1的子串都是回文
    for(int i = 0; i < slen; ++i){
        g_cnt[i][i] = 1;
    }
    
    for(int len = 2; len <= slen; ++len){ //長度從小到大處理子串
        for(int i = 0; i < slen; ++i){
            int left = i;
            int right = i + len - 1;
            if( left < 0 || right >= slen){
                continue;
            }
            //左右兩個字符相等,且中間部分也是回文
            if(s[left] == s[right] && g_cnt[left + 1][right - 1] == len - 2){
                g_cnt[left][right] = g_cnt[left + 1][right - 1] + 2;
            }
            else{
                g_cnt[left][right] = max(g_cnt[left + 1][right], g_cnt[left][right - 1]);
            }
        }
    }

    return g_cnt[0][slen - 1]; //整個字符串的最長回文長度即為所求值。
}

int main(int argc, char **argv){
    //測試用字符串
    const char *strings[] = {
        "abxabaxbmd",
        "aabbccddcbaabc",
        "aa",
        "aba",
        "a",
        "abba",
        "abcba",
        "xabcbam"
    };
    for(int i = 0; i < sizeof(strings) / sizeof(strings[0]); ++i){
        fprintf(stdout, "%s\t%d\n", strings[i], dp_maxlen(strings[i]));
    }
    return 0;
}
本文由《純淨天空》出品。文章地址: https://vimsky.com/zh-tw/article/991.html,未經允許,請勿轉載。