C语言实现求一个字符串的最长回文字串 动态规划

求解思路:

  • 回文字符串的子串也是回文,比如P[i,j](表示以i开始以j结束的子串)是回文字符串,
  • 那么P[i+1,j-1]也是回文字符串。这样最长回文子串就能分解成一系列子问题了。
  • 这样需要额外的空间O(N2),算法复杂度也是O(N2)。
  • 首先定义状态方程和转移方程:
  • P[i,j]=0表示子串[i,j]不是回文串。P[i,j]=1表示子串[i,j]是回文串。
  • P[i,i]=1
  • P[i,j]{=P[i+1,j-1],if(s[i]==s[j])
  • =0 ,if(s[i]!=s[j])}
#include 
#include 
#include 

char* longestpalindrome(const char *str)
{
    bool dp[100][100];
    int i,j,len;
    int longest = 1;//最长子串的长度
    int tmp;
    int n = strlen(str);
    char a[n];//最长子串存放位置
    for(i = 0; i < n; i++)
    {
        dp[i][i] = 1;
        if(str[i] == str[i + 1])
        {
            dp[i][i + 1] = 1;
            longest = 2;
            strncpy(a,str + i,2);
        }
    }
    for(len = 3; len <= n; len++)//子串长度
    {
        for(i = 0; i <= n - len; i++)//子串起始位置
        {
            j = i + len - 1;
            if(str[i] == str[j])
            {
                dp[i][j] = dp[i + 1][j - 1];
                if(dp[i][j] == 1)
                {
                    tmp = j - i + 1;
                    if(longest < tmp)
                    {
                        longest = tmp;
                        strncpy(a,str + i,tmp);
                    }
                }
            }
            else
                dp[i][j] = 0;
        }
    }
    printf("%d\n",longest);
    char *s = a;       
    return s;
}

int main()
{
    char a[20];
    scanf("%s",a);
    char *s = longestpalindrome(a);
    printf("%s\n",s);
}

你可能感兴趣的:(C语言,C语言的学习历程)