字符串回文问题及其扩展
2014-09-25 12:35
211 查看
对称symmetry/回文palindrome问题:
(一)回文定义:
回文即对称,如"abcba","abba";
(二)判断是否对称/回文:
(1)方法一:从两端开始向中间扫描,知道相遇,对应的元素都一样,则是对称的,否则不是。
bool isSymmetry(const char * str,int left ,int right){
while(left<right){
if(str[left]!=str[right])
return false;
else {
left++;
right--;
}
}
return true;
}
(2)方法二:从中间向两边扫描;
/*长度为:len=right-left+1*/
bool isSymmetry(char * str ,int left, int right){
int halflen=(right-left)/2;
int mid1=halflen+left;//mid1往左边扫描
int mid2=right-halflen;//mid2往右边扫描
for(int i=0;i<=halflen;i++){
if(str[mid1-i]!=str[mid2+i])
return false;
}
return true;
}
(3)方法三:将字符串逆序(栈实现),然后扫描两个字符串,如果一直相等,则是回文。
(三)应用:寻找一个字符串的最大对称子串:
(1)方法一:
1)分析:
查找最大对称子串,应该从最大长度开始,找到则返回。不可以从最小的开始。
2)代码实现:
/*时间复杂度为O(n^3)*/
char * max_SubSymmetryStr(char * str, int length){
char* subString=(char *) malloc(sizeof(char)*length);
int Symmetry;//判断是否对称
for(int len=length;len>0;len--){
for(int j=0;j+len-1<length;j++){
//j,j+len-1分别是长为len的字符串的首字符和最后一个字符的下标。
subString=str.subString(j,j+len-1);
//获取str的从j到j+len的子串。
Symmetry=isSymmetry(subString ,0,len-1);
if(1==Symmetry)
return subString;
}
}
}
(2)方法二:扩展法;
1)思想:
从一个字符开始,向两边扩展,看看最多能到多长,使其保持为回文。
2)代码实现:
/*
一个字符串中的最长的对称子串,然后返回对称长度。
时间复杂度为O(n^2)
*/
int max_subSemmetry(char * str , int n){
int maxLen,tempLen;
if(NULL==str || n=0) return 0;
maxLen=0;
int mid,halflen;
//mid表示向两边扩展的中心点,halflen表示对称的字符的长度的一半。
for(mid=0; mid<n;mid++){
for(halflen=0;(halflen+mid)<=n-1 &&(mid-halflen)>=0;halflen++){
if(str[mid-halflen]!= str[mid+halflen]) break;
}
//回文串的长度的 一半为奇数odd。
if(halflen*2+1>maxLen) maxLen=halflen*2+1;
for(halflen=0; (mid-halflen)>=0 && (mid+halflen+1)<=n-1;halflen++){
if(str[mid-halflen]!=str[mid+halflen+1]) break;
}
//回文串的长度的 一半为偶数even。
if(halflen*2+2>maxLen) maxLen=halflen*2+2;
}
return maxLen;
}
(一)回文定义:
回文即对称,如"abcba","abba";
(二)判断是否对称/回文:
(1)方法一:从两端开始向中间扫描,知道相遇,对应的元素都一样,则是对称的,否则不是。
bool isSymmetry(const char * str,int left ,int right){
while(left<right){
if(str[left]!=str[right])
return false;
else {
left++;
right--;
}
}
return true;
}
(2)方法二:从中间向两边扫描;
/*长度为:len=right-left+1*/
bool isSymmetry(char * str ,int left, int right){
int halflen=(right-left)/2;
int mid1=halflen+left;//mid1往左边扫描
int mid2=right-halflen;//mid2往右边扫描
for(int i=0;i<=halflen;i++){
if(str[mid1-i]!=str[mid2+i])
return false;
}
return true;
}
(3)方法三:将字符串逆序(栈实现),然后扫描两个字符串,如果一直相等,则是回文。
(三)应用:寻找一个字符串的最大对称子串:
(1)方法一:
1)分析:
查找最大对称子串,应该从最大长度开始,找到则返回。不可以从最小的开始。
2)代码实现:
/*时间复杂度为O(n^3)*/
char * max_SubSymmetryStr(char * str, int length){
char* subString=(char *) malloc(sizeof(char)*length);
int Symmetry;//判断是否对称
for(int len=length;len>0;len--){
for(int j=0;j+len-1<length;j++){
//j,j+len-1分别是长为len的字符串的首字符和最后一个字符的下标。
subString=str.subString(j,j+len-1);
//获取str的从j到j+len的子串。
Symmetry=isSymmetry(subString ,0,len-1);
if(1==Symmetry)
return subString;
}
}
}
(2)方法二:扩展法;
1)思想:
从一个字符开始,向两边扩展,看看最多能到多长,使其保持为回文。
2)代码实现:
/*
一个字符串中的最长的对称子串,然后返回对称长度。
时间复杂度为O(n^2)
*/
int max_subSemmetry(char * str , int n){
int maxLen,tempLen;
if(NULL==str || n=0) return 0;
maxLen=0;
int mid,halflen;
//mid表示向两边扩展的中心点,halflen表示对称的字符的长度的一半。
for(mid=0; mid<n;mid++){
for(halflen=0;(halflen+mid)<=n-1 &&(mid-halflen)>=0;halflen++){
if(str[mid-halflen]!= str[mid+halflen]) break;
}
//回文串的长度的 一半为奇数odd。
if(halflen*2+1>maxLen) maxLen=halflen*2+1;
for(halflen=0; (mid-halflen)>=0 && (mid+halflen+1)<=n-1;halflen++){
if(str[mid-halflen]!=str[mid+halflen+1]) break;
}
//回文串的长度的 一半为偶数even。
if(halflen*2+2>maxLen) maxLen=halflen*2+2;
}
return maxLen;
}
相关文章推荐
- 《动态规划》之--字符串比较问题(扩展距离)
- 安装VS2003出现问题——Microsoft FrontPage 2000 Web 扩展客户端安装不成功 及其解决方法
- 判断链表中是否存在环问题、判断两个链表是否相交问题及其扩展
- C语言回文及其转化问题
- 剑指offer————字符串组合扩展题目立方体放数问题
- C++实现 八皇后问题及其扩展N皇后问题(经典回溯算法)
- 判断链表有环及其扩展问题
- 问题6: 找出字符串中出现次数最多的字母及其出现的次数
- JSON(3):Java的Date类型转换为符合json语法的字符串遇到的问题及其解决办法
- 一道特殊的回文字符串处理问题
- 回文字符串 的添加问题
- 数据结构与算法复习(20)—— KMP 与字符串算法及其扩展
- 编程之美3.1字符串移位包含的问题的扩展问题
- 回文字符串及其变种
- 数组字符串问题------求数组前k小的元素,及其应用
- 字符串实际长度及其根据实际长度截取的问题
- 八皇后问题及其扩展N皇后问题(经典回溯算法)
- 最长对称字符串问题/最长回文子串问题
- 求最大子数组之和及其一些扩展问题
- 最长回文子串算法(字符串处理问题+多种方法解决)【转载】