首页 > 代码库 > 最长回文子串
最长回文子串
一般求回文子串用的是Manacher算法,但是该算法只是简单判断回文,该题目中需要去除掉空格和标点,所以,自己用了动态规划(加剪枝,取出空号等)。
代码如下:
//最长回文子串 动态规划 #include<cstdlib> #include<cstring> #include<cstdio> #include<cctype> //for tolower #define MAXSIZE 5000 char str[MAXSIZE];//="Confuciuss say:Madam,I'm Adam."; int d[MAXSIZE]; //表示状态,以i为末节点的回文长度 int begin[MAXSIZE]; //以i为末节点的回文序列的起始位置在哪 #define COMP(x) ((str[x]<='z'&&str[x]>='a')||(str[x]<='Z'&&str[x]>='A')) void printstr() //输入字符串 { int i=0; char sh; printf("请输入样例:"); scanf("%c",&sh); while(sh!='\n') { str[i++]=sh; scanf("%c",&sh); } str[i]=0; } int main() { freopen("a.txt","r",stdin); printstr(); int len=strlen(str); int i,j,k,num=1,flag=0; d[0]=COMP(0)?1:-1; begin[0]=d[0]?0:-1; for(i=1;i<len;i++) { if(!COMP(i)) { d[i]=-1; begin[i]=-1; continue; } //给一个默认的初始化 d[i]=1; begin[i]=i; j=i-1; while(d[j]==-1&&j>=0) j--; //循环之后,确定j指定的位置一定是字母或者为-1 if(j<0) continue; if(d[j]==1) { //case1: a a if(tolower(str[j])==tolower(str[i])) { d[i]=d[j]+1; begin[i]=j; } // case2: ac a else if(j-1>=0) { k=j-1; while(d[k]==-1&&k>=0) k--; if(k>=0&&tolower(str[k])==tolower(str[i])) { d[i]=d[j]+2; begin[i]=k; } } } else { //case3: sssss s char same=tolower(str[begin[j]]); for(k=begin[j]+1;k<=j;k++) { if(COMP(k)) { if(tolower(str[k])!=same) break; } } if(k==j+1&&tolower(str[i])==same) { d[i]=d[j]+1; begin[i]=begin[j]; } //case4: sdad s else { int temp=begin[j]-1; while(d[temp]==-1&&temp>=0) temp--; if(temp<0) ; else if(tolower(str[temp])==tolower(str[i])) { d[i]=d[j]+2; begin[i]=temp; } } } if(d[i]>num) { num=d[i]; flag=begin[i]; } else if(d[i]==num&&begin[i]<flag) flag=begin[i]; } printf("请输出样例:"); for(i=flag,k=1;k<=num;i++) { if(COMP(i)) k++; printf("%c",str[i]); } //printf("%d\n",num); return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。