C语言 最长回文子串

描述:输入一个字符串,求其中最长回文子串。子串的含义是:在字符串中连续出现得字符串片段。回文的含义是,

正着看和倒着看是相同的,如abba何abbebba。在判断时要求忽略所有的标点和空格,且忽略大小写。但输出时按原样输出

(首尾不要输出多余的字符串).输入字符串长度大于等于1小于等于5000.且单独占一行。

输入:

输入一行字符串。

输出:

输出所要求的回文子串。

样例输入:

Last Week,todo level odot,King

样例输出:

k,todo level odot,K

代码:

#include<stdio.h>
#include<string.h>
#include<ctype.h>
int main()
{
    char s[5000],s1[5000];int i,j,m=0,pri[5000],max=0,x,y,n;
    gets(s);
    n=strlen(s);
    for (i=0;i<n;i++)
    {

      if(isalpha(s[i]))
      {
          pri[m]=i;
          s1[m++]=toupper(s[i]);

      }
    }
    for (i=0;i<m;i++)
    {

            for (j=0;j<=i&&i+j<m;j++)
        {
            if(s1[i-j]!=s1[i+j])break;//奇数
            if((2*j+1)>max)
              {
                  max=2*j+1;
                  x=pri[i-j];
                  y=pri[i+j];
              }
        }
             for (j=0;j<=i&&i+j<m;j++)
        {
            if (s1[i-j]!=s1[i+j+1])break;//偶数
            if ((2*j+2)>max)
            {
                max=2*j+2;
                x=pri[i-j];
                y=pri[i+j+1];
            }
        }


    }
    for (i=x;i<=y;i++)
        printf("%c",s[i]);
    return 0;
}

 

有两种常见的C语言实现寻找最长回文子串的方法,分别是动态规划和Manacher算法。 ### 动态规划实现 ```c #include <stdio.h> #include <string.h> #include <stdlib.h> char * longestPalindrome(char * s){ if (s == NULL || strlen(s) < 2) { return s; } int dp[1000][1000] = {0}; int maxLen = 1; int startP = 0; int endP = 0; for (int i = 1; i < strlen(s); i++) { for (int j = 0; j < i; j++) { if ((s[i] == s[j]) && (((i - j) <= 2) || (dp[i - 1][j + 1] == 1))) { dp[i][j] = 1; if (i - j + 1 > maxLen) { maxLen = i - j + 1; startP = j; endP = i; } } } } char *ret = (char *)malloc(sizeof(char) * (maxLen + 1)); for (int i = 0; i < maxLen; i++){ ret[i] = s[i + startP]; } ret[maxLen] = 0; return ret; } ``` 该实现的思路是使用动态规划的思想,创建一个二维数组`dp`,其中`dp[i][j]`表示从索引`i`到索引`j`的子串是否为回文串。通过遍历所有长度的子串,从最短的子串起,依次判断是否为回文串,并根据判断结果更新最长回文子串。最后,返回最长回文子串。该算法的时间复杂度为$O(n^2)$,其中`n`是字符串的长度,双重循环遍历了所有长度为 1 到`n`的子串。空间复杂度为$O(n^2)$,存储了一个二维数组`dp` [^2][^4]。 ### Manacher算法实现 ```c #include <stdio.h> #include <string.h> #include <stdlib.h> // 插入特殊字符预处理 void preprocess(char *s, char *t) { int n = strlen(s); t[0] = '$'; t[1] = '#'; for (int i = 0; i < n; i++) { t[2 * i + 2] = s[i]; t[2 * i + 3] = '#'; } t[2 * n + 2] = '\0'; } // Manacher算法 char * longestPalindromeManacher(char * s) { int n = strlen(s); if (n == 0) return ""; char t[2 * n + 3]; preprocess(s, t); int len = strlen(t); int p[2 * n + 3] = {0}; int c = 0, r = 0; for (int i = 1; i < len - 1; i++) { int i_mirror = 2 * c - i; if (r > i) { p[i] = (r - i < p[i_mirror]) ? r - i : p[i_mirror]; } else { p[i] = 0; } while (t[i + 1 + p[i]] == t[i - 1 - p[i]]) { p[i]++; } if (i + p[i] > r) { c = i; r = i + p[i]; } } int maxLen = 0; int centerIndex = 0; for (int i = 1; i < len - 1; i++) { if (p[i] > maxLen) { maxLen = p[i]; centerIndex = i; } } int start = (centerIndex - maxLen) / 2; char *ret = (char *)malloc(sizeof(char) * (maxLen + 1)); strncpy(ret, s + start, maxLen); ret[maxLen] = '\0'; return ret; } ``` Manacher算法的思想是避免"匹配"失败后的下标回退,从而进一步优化算法的时间复杂度。通过在字符间插入特殊字符,牺牲空间换时间。该算法的时间复杂度为$O(n)$,空间复杂度为$O(n)$ [^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值