• 《算法竞赛入门经典》3.3最长回文子串


      1     //例题3-4  
      2     /*  
      3     * 输入一个字符串,求出其中最长的回文子串。子串的含义是:在原串中连续出现的字符串片段。 
      4     *回文的含义是:正看着和倒看着相同,如abba和yyxyy。在判断时,应该忽略所有标点符号和空格 
      5     *且忽略大小写,但输出应保持原样(在回文串的首部和尾部不要输出多余字符)。输入字符长度不超过5000 
      6     *且占据单独的一行。应该输出最长回文串,如果有多个,输出起始位置最靠左的。 
      7     *样例输入:Confuciuss say:Madam,I'm Adam. 
      8     *样例输出:Madam,I'm Adam 
      9     */  
     10       
     11     //程序3-5 最长回文子串(1)  
     12     #include<stdio.h>  
     13     #include<string.h>  
     14     #include<ctype.h>     //用到isalpha、touuper等工具  
     15     #define MAXN 5000+10  
     16     char buf[MAXN],s[MAXN];  
     17     int main()  
     18     {  
     19         int n,m=0,max=0;  
     20         int i,j,k;  
     21         fgets(buf,sizeof(s),stdin);     //从标准输入流中读取sizeof(s)-1个字符并且把他们转储到buf中  
     22         n=strlen(buf);                  //获取buf的长度,包含文件结束符''  
     23         for(i=0;i<n;i++)    
     24                                 //构造一个新的字符串,把标点符号过滤掉,随便把小写字母变为大写  
     25             if(isalpha(buf[i])) s[m++]=toupper(buf[i]);  
     26         for(i=0;i<m;i++)     //其中m是新字符串s的长度  
     27             for(j=i;j<m;j++)  
     28             {  
     29                 int ok=1;  
     30                 for(k=i;k<=j;k++)    //判断s[i..j]是否为回文串  
     31                     if(s[k]!=s[i+j-k]) ok=0;      
     32                 if(ok && j-i+1>max) max=j-i+1;   //保存当前发现的最长回文串  
     33             }  
     34             printf("max=%d
    ",max);  
     35             return 0;  
     36     }  
     37       
     38       
     39     //程序3-5 最长回文子串(2)  
     40     #include<stdio.h>  
     41     #include<string.h>  
     42     #include<ctype.h>     //用到isalpha、touuper等工具  
     43     #define MAXN 5000+10  
     44     char buf[MAXN],s[MAXN];  
     45     int p[MAXN];            //增设数组p,用于保存s[i]在buf中的位置  
     46     int main()  
     47     {  
     48         int n,m=0,max=0,x,y;  
     49         int i,j,k;  
     50         fgets(buf,sizeof(s),stdin); //从标准输入流中读取sizeof(s)-1个字符并且把他们转储到buf中  
     51         n=strlen(buf);              //获取buf的长度,包含文件结束符''  
     52         for(i=0;i<n;i++)  
     53             if(isalpha(buf[i]))     //构造一个新的字符串,把标点符号过滤掉,随便把小写字母变为大写  
     54                 {  
     55                     p[m]=i;         //保存s[m]在buf的位置  
     56                     s[m++]=toupper(buf[i]);   
     57             }  
     58             for(i=0;i<m;i++)     //遍历字符串s,以i为"中间"位置,然后根据j的值不断向两边扩展  
     59             {                       //这个for循环遍历的子串长度为奇数  
     60                 for(j=0;i-j>=0 && i+j<m; j++) //注意i和j的关系:i-j>=0表示i到j的距离不能上溢  
     61                                                 //i+j<m表示i再加j个位置没有超过字符串s的总长  
     62                 {  
     63                     if(s[i-j]!=s[i+j]) break;   //如果以i为中间点,左边i-j个点字符跟右边i+j个点不同,跳出循环  
     64                     if(j*2+1>max)                //因为子串的长度为奇数,所以子串的长度应该等于j*2+1(j为以i为中心,往两边的距离)  
     65                     { max=j*2+1; x=p[i-j];y=p[i+j]; } //保存当前最长回文子串长度,记录子串范围  
     66                 }  
     67                 for(j=0;i-j>=0 && i+j+1<m; j++)//这个for循环遍历的子串长度为偶数,  
     68                     //中间点i取子串长度的中点,导致两边长度不均,右边的距离应该再加1  
     69                 {  
     70                     if(s[i-j]!=s[i+j+1]) break;  
     71                     if(j*2+2>max)            
     72                     { max=j*2+2; x=p[i-j]; y=p[i+j+1]; }  
     73                 }  
     74             }  
     75             for(i=x;i<=y;i++)    //把最长回文子串输出  
     76                 printf("%c",buf[i]);  
     77             printf("
    ");  
     78             return 0;  
     79     }  
     80       
     81       
     82     /*样例输入:Confuciuss say:Madam,I'm Adam. 
     83     *样例输出:Madam,I'm Adam 
     84     * 
     85     //分析得出最长回文子串的过程 
     86     *(1)    for(i=0;i<m;i++)     //遍历字符串s,以i为"中间"位置,然后根据j的值不断向两边扩展 
     87             {                       //这个for循环遍历的子串长度为奇数 
     88     *(2)        for(j=0;i-j>=0 && i+j<m; j++) //注意i和j的关系:i-j>=0表示i到j的距离不能上溢 
     89                                                 //i+j<m表示i再加j个位置没有超过字符串s的总长 
     90                 { 
     91                     if(s[i-j]!=s[i+j]) break;   //如果以i为中间点,左边i-j个点字符跟右边i+j个点不同,跳出循环 
     92                     if(j*2+1>max)                //因为子串的长度为奇数,所以子串的长度应该等于j*2+1(j为以i为中心,往两边的距离) 
     93                     { max=j*2+1; x=p[i-j];y=p[i+j]; } //保存当前最长回文子串长度,记录子串范围 
     94                 } 
     95     *(3)        for(j=0;i-j>=0 && i+j+1<m; j++)//这个for循环遍历的子串长度为偶数, 
     96                     //中间点i取子串长度的中点,导致两边长度不均,右边的距离应该再加1 
     97                 { 
     98                     if(s[i-j]!=s[i+j+1]) break; 
     99                     if(j*2+2>max)           
    100                     { max=j*2+2; x=p[i-j]; y=p[i+j+1]; } 
    101                 } 
    102             } 
    103     *字符串s="CONFUCIUSSSAYMADAMIMADAM" 
    104     *字符串长度m=24 
    105     *第一个for循环循环到i=18的时候 
    106     *也就是遍历到s[18]位置上,这时s[18]='I' 
    107     *接着进行内部循环,执行第二个循环体,开始以I为中心点,向两边扩展 
    108     *i=18,j=0,满足条件,执行if语句,s[i-j]=I,s[i+j]=I,s[i-j]=s[i+j]不满足条件 
    109     *执行下一条if语句,判断j*2+1是否大于max,0*2+1<max=5,不满足条件,因为之前第一个回文子串是MADAM,长度为5 
    110     *j=1;s[i-j]=M,s[i+j]=M;不满足条件 
    111     *j*2+1<max,max=5,p[i-j]=17,p[i+j]=19 
    112     *j=2;s[i-j]=A;s[i+j]=A; 
    113     *j*2+1=max,max=5,p[i-j]=16,p[i+j]=20 
    114     *j=3;s[i-j]=D;s[i+j]=D; 
    115     *j*2+1>max,max=7,p[i-j]=15,p[i+j]=21 
    116     *j=4;s[i-j]=A;s[i+j]=A; 
    117     *j*2+1>max,max=9,p[i-j]=14,p[i+j]=22 
    118     *j=5;s[i-j]=M;s[i+j]=M; 
    119     *j*2+1>max,max=11,p[i-j]=13,p[i+j]=23,x=13,y=23 
    120     *j=6;i+j>m,结束本次循环 
    121     *继续执行下一个for语句 
    122     *i=18,j=0,满足循环条件,执行循环体 
    123     *s[i-j]!=s[i+j+1];满足条件,break跳出循环 
    124     *到此最长的回文子串已经得出来了,不过还要继续遍历字符串,直到结束为止 
    125     *最后结果:Madam,I'm Adam 
    126     */  
    亲爱的读者:如果觉得本文对你有所帮助,请点击推荐,分享给其他人!
  • 相关阅读:
    每日一水 POJ8道水题
    编译和使用 MySQL C++ Connector
    j2ee model1模型完成分页逻辑的实现 详解!
    DB查询分析器访问EXCEL时,要在表名前后加上中括弧或双引号
    指向结构体变量的指针
    EOSS V3.0 企业运营支撑系统(基于RBAC原理的权限管理)
    MybatisGen1.0 Mybatis JavaBean Mapper生成工具
    The table name must be enclosed in double quotation marks or sqare bracket while accessing EXCEL by
    资源-Android:Android
    软件-开发软件:Android Studio
  • 原文地址:https://www.cnblogs.com/zhuangwei/p/5243608.html
Copyright © 2020-2023  润新知