对称字符串的最大长度

简介: 题目:输入一个字符串,输出该字符串中对称的子字符串的最大长度。比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。 思路:可能很多人写过判断一个字符串是不是对称函数,这个题目可以看成是该函数的加强版。

 

题目:输入一个字符串,输出该字符串中对称的子字符串的最大长度。比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。


思路:可能很多人写过判断一个字符串是不是对称函数,这个题目可以看成是该函数的加强版。首先想到的就是遍历,暂且先不考虑效率问题。判断一个字符串是不是对称的函数,可以用这个字函数逐一检查原字符串中所有的子字符串,然后输出长度最大的即可。

怎样判断一个字符串是不是对称的字符串?

-->可以用两个指针分别指向字符串的第一个字符和最后一个字符,判断是否相等,如果不相等直接返回false,如果为真则接着比较下  一对字符。

如何遍历原字符串的所有字串?首先让一个指针从头至尾遍历,对于这个指针的每一个字符,我们再用另一个指针逐一指向它后面的每一个字符即可。

判断字符串是否对称

        要判断一个字符串是不是对称的,不是一件很难的事情。我们可以先得到字符串首尾两个字符,判断是不是相等。如果不相等,那该字符串肯定不是对称的。否则我们接着判断里面的两个字符是不是相等,以此类推。基于这个思路,我们不难写出如下代码:

 

  1. bool IsSymmetrical(char *pBegin , char *pEnd)  
  2. {  
  3.     if(pBegin == NULL || pEnd == NULL || pBegin > pEnd)  
  4.         return false;  
  5.   
  6.     while(pBegin < pEnd)  
  7.     {  
  8.         if(*pBegin != *pEnd)  
  9.             return false;  
  10.   
  11.         pBegin++;  
  12.         pEnd--;  
  13.     }  
  14.   
  15.     return true;  
  16. }  

 

       要判断一个字符串pString是不是对称的,我们只需要调用IsSymmetrical(pString, &pString[strlen(pString) – 1])就可以了。

解法一:On3)的算法

现在我们试着来得到对称子字符串的最大长度。最直观的做法就是得到输入字符串的所有子字符串,并逐个判断是不是对称的。如果一个子字符串是对称的,我们就得到它的长度。这样经过比较,就能得到最长的对称子字符串的长度了。于是,我们可以写出如下代码:

  1. ////////////////////////////////////////////////////////////////  
  2.   
  3. // Get the longest length of its all symmetrical substrings  
  4.   
  5. // Time needed is O(T^3)  
  6.   
  7. ////////////////////////////////////////////////////////////////  
  8.   
  9. int GetLongestSymmetricalLength_1(char* pString)  
  10.   
  11. {  
  12.   
  13.        if(pString == NULL)  
  14.   
  15.               return 0;  
  16.   
  17.    
  18.   
  19.        int symmeticalLength = 1;  
  20.   
  21.    
  22.   
  23.        char* pFirst = pString;  
  24.   
  25.        int length = strlen(pString);  
  26.   
  27.        while(pFirst < &pString[length - 1])  
  28.   
  29.        {  
  30.   
  31.               char* pLast = pFirst + 1;  
  32.   
  33.               while(pLast <= &pString[length - 1])  
  34.   
  35.               {  
  36.   
  37.                      if(IsSymmetrical(pFirst, pLast))  
  38.   
  39.                      {  
  40.   
  41.                            int newLength = pLast - pFirst + 1;  
  42.   
  43.                            if(newLength > symmeticalLength)  
  44.   
  45.                                   symmeticalLength = newLength;                           
  46.   
  47.                      }  
  48.   
  49.    
  50.   
  51.                      pLast++;  
  52.   
  53.               }  
  54.   
  55.    
  56.   
  57.               pFirst++;  
  58.   
  59.        }  
  60.   
  61.    
  62.   
  63.        return symmeticalLength;  
  64.   
  65. }  


因此解法一实现代码如下:

 

  1. #include<iostream>  
  2. #include<string.h>  
  3. using namespace std;  
  4.   
  5. /*************************** 
  6. *判断一个字符串是否对称 
  7. ***************************/  
  8. bool IsSymmetrical(char *pBegin , char *pEnd)  
  9. {  
  10.     if(pBegin == NULL || pEnd == NULL || pBegin > pEnd)  
  11.         return false;  
  12.   
  13.     while(pBegin < pEnd)  
  14.     {  
  15.         if(*pBegin != *pEnd)  
  16.             return false;  
  17.   
  18.         pBegin++;  
  19.         pEnd--;  
  20.     }  
  21.   
  22.     return true;  
  23. }  
  24.   
  25. /*************************** 
  26. *求最大对称字串的长度 
  27. ***************************/  
  28. int GetLongestSymmerticalLength(char *pString)  
  29. {  
  30.     if(pString == NULL)  
  31.         return 0;  
  32.   
  33.     int symmerticalLength = 1;  
  34.   
  35.     char *pFirst = pString;  
  36.     int length = strlen(pString);  
  37.     while(pFirst < &pString[length - 1])  
  38.     {  
  39.         char *pLast = pFirst + 1;  
  40.         while(pLast <= &pString[length - 1])  
  41.         {  
  42.             if(IsSymmetrical(pFirst , pLast))  
  43.             {  
  44.                 int newLength = pLast - pFirst + 1;  
  45.                 if(newLength > symmerticalLength)  
  46.                     symmerticalLength = newLength;  
  47.             }  
  48.   
  49.             pLast++;  
  50.         }  
  51.           
  52.         pFirst++;  
  53.     }  
  54.     return symmerticalLength;  
  55. }  
  56.   
  57. int main()  
  58. {  
  59.     cout<<"Please enter your string(the length must < 1000):"<<endl;  
  60.     char *yourstring = new char[1000];  
  61.     cin>>yourstring;  
  62.     cout<<"The max symmetrical subString length is :"<<endl;  
  63.     cout<<GetLongestSymmerticalLength(yourstring)<<endl;  
  64.   
  65.     delete[] yourstring;  
  66.         system("pause");  
  67.     return 0;  
  68. }  

 

我们来分析一下上述方法的时间效率。由于我们需要两重while循环,每重循环需要On)的时间。另外,我们在循环中调用了IsSymmetrical,每次调用也需要On)的时间。因此整个函数的时间效率是On3)。

通常On3)不会是一个高效的算法。如果我们仔细分析上述方法的比较过程,我们就能发现其中有很多重复的比较。假设我们需要判断一个子字符串具有aAa的形式(AaAa的子字符串,可能含有多个字符)。我们先把pFirst指向最前面的字符a,把pLast指向最后面的字符a,由于两个字符相同,我们在IsSymtical函数内部向后移动pFirst,向前移动pLast,以判断A是不是对称的。接下来若干步骤之后,由于A也是输入字符串的一个子字符串,我们需要再一次判断它是不是对称的。也就是说,我们重复多次地在判断A是不是对称的。

造成上述重复比较的根源在于IsSymmetrical的比较是从外向里进行的。在判断aAa是不是对称的时候,我们不知道A是不是对称的,因此需要花费On)的时间来判断。下次我们判断A是不是对称的时候,我们仍然需要On)的时间。

解法二:On2)的算法

如果我们换一种思路,我们从里向外来判断。也就是我们先判断子字符串A是不是对称的。如果A不是对称的,那么向该子字符串两端各延长一个字符得到的字符串肯定不是对称的。如果A对称,那么我们只需要判断A两端延长的一个字符是不是相等的,如果相等,则延长后的字符串是对称的。因此在知道A是否对称之后,只需要O1)的时间就能知道aAa是不是对称的。

我们可以根据从里向外比较的思路写出如下代码:


  1. #include<iostream>  
  2. #include<string.h>  
  3. using namespace std;  
  4.   
  5. int GetLongestSymmeticalLength(char *pString)  
  6. {  
  7.     if(pString == NULL)  
  8.         return 0;  
  9.     int symmeticalLength = 1;  
  10.   
  11.     char *pChar = pString;  
  12.     while(*pChar != '\0')  
  13.     {  
  14.         //substring with odd length(奇数)  
  15.         char *pFirst = pChar - 1;  
  16.         char *pLast = pChar + 1;  
  17.         while(pFirst >= pString && *pLast != '\0' && *pFirst == *pLast)  
  18.         {  
  19.             pFirst--;  
  20.             pLast++;  
  21.         }  
  22.   
  23.         int newLength = pLast - pFirst - 1; //注意此时是减1  
  24.         if(newLength > symmeticalLength)  
  25.             symmeticalLength = newLength;  
  26.   
  27.   
  28.         //substring with even length(偶数)  
  29.         pFirst = pChar;  
  30.         pLast = pChar + 1;  
  31.         while(pFirst >= pString && *pLast != '\0' && *pFirst == *pLast)  
  32.         {  
  33.             pFirst--;  
  34.             pLast++;  
  35.         }  
  36.   
  37.         newLength = pLast - pFirst - 1;  
  38.         if(newLength > symmeticalLength)  
  39.             symmeticalLength = newLength;  
  40.   
  41.         pChar++;  
  42.     }  
  43.   
  44.     return symmeticalLength;  
  45. }  
  46.   
  47. int main()  
  48. {  
  49.     cout<<"Please enter your string(the length must < 1000):"<<endl;  
  50.     char *yourstring = new char[1000];  
  51.     cin>>yourstring;  
  52.     cout<<"The max symmetrical subString length is :"<<endl;  
  53.     cout<<GetLongestSymmeticalLength(yourstring)<<endl;  
  54.   
  55.     delete[] yourstring;  
  56.     system("pause");  
  57.     return 0;  
  58. }  



由于子字符串的长度可能是奇数也可能是偶数。长度是奇数的字符串是从只有一个字符的中心向两端延长出来,而长度为偶数的字符串是从一个有两个字符的中心向两端延长出来。因此我们的代码要把这种情况都考虑进去。

在上述代码中,我们从字符串的每个字符串两端开始延长,如果当前的子字符串是对称的,再判断延长之后的字符串是不是对称的。由于总共有On)个字符,每个字符可能延长On)次,每次延长时只需要O1)就能判断出是不是对称的,因此整个函数的时间效率是On2)。

参考:http://zhedahht.blog.163.com/blog/static/25411174201063105120425/             http://blog.csdn.net/zz198808/article/details/7795132

img_e00999465d1c2c1b02df587a3ec9c13d.jpg
微信公众号: 猿人谷
如果您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】
如果您希望与我交流互动,欢迎关注微信公众号
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

相关文章
|
存储 安全 数据管理
电脑硬盘分区及合并指南
本文介绍了电脑硬盘分区的方法,包括使用Windows磁盘管理器和第三方工具如DiskGenius。创建新分区涉及打开磁盘管理,右键未分配空间新建简单卷。第三方软件可快速分区或拆分分区,但需注意数据备份。合并分区时,删除目标分区后扩展相邻分区,操作前务必备份数据。安全和合理规划硬盘空间是关键。
电脑硬盘分区及合并指南
|
存储 编译器 程序员
抽丝剥茧C语言(高阶)程序环境和预处理
抽丝剥茧C语言(高阶)程序环境和预处理
|
9天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1200 4
|
8天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
1149 87
|
7天前
|
机器学习/深度学习 物联网
Wan2.2再次开源数字人:Animate-14B!一键实现电影角色替换和动作驱动
今天,通义万相的视频生成模型又又又开源了!Wan2.2系列模型家族新增数字人成员Wan2.2-Animate-14B。
621 11
|
9天前
|
云栖大会
阿里云云栖大会2025年9月24日开启,免费申请大会门票,速度领取~
2025云栖大会将于9月24-26日举行,官网免费预约畅享票,审核后短信通知,持证件入场
1738 12
|
18天前
|
人工智能 运维 安全
|
9天前
|
消息中间件 Java Apache
SpringBoot集成RocketMq
RocketMQ 是一款开源的分布式消息中间件,采用纯 Java 编写,支持事务消息、顺序消息、批量消息、定时消息及消息回溯等功能。其优势包括去除对 ZooKeeper 的依赖、支持异步和同步刷盘、高吞吐量及消息过滤等特性。RocketMQ 具备高可用性和高可靠性,适用于大规模分布式系统,能有效保障消息传输的一致性和顺序性。
528 2

热门文章

最新文章