对称子字符串的最大长度
2012-09-03 22:06
260 查看
【题 目】输入一个字符串,输出该字符串中最大对称子串的长度。例如输入字符串:“google”,该字符串中最长的子字符串是“goog”,长度为4,因而输出为4。
【思 路1】一看这题就是遍历!没错,我们最直观的往往也是最容易实现的,这里我们暂且不考虑效率的问题。我们的基本思路是:我们如果有一个判断一个字符串是不是对称的函数的话,我们就可以用这个子函数逐一检查原字符串中所有的字符串,然后输出长度最大的即可。
(1)怎样判断一个字符串是不是对称的字符串?我们可以用两个指针分别指向字符串的第一个字符和最后一个字符,判断是否相等,如果不等直接返回false,如果为真则接着比较下一对字符。(2)如果遍历遍历原字符串的所有子串,首先我们让一个指针从头至尾遍历,对于这个指针的每一个字符,我们在用另一个指针逐一指向它后面的每一个字符即可。好了,两个问题都解决了,我们可以写出如下的代码:
运行结果如下:
反思:我们现在来分析一下该算法的时间复杂度,首先遍历原字符串的所有子串有两个循环,这个时间复杂度是O(n2),我们在这两层循环之间有一个判断给定字符串是不是对称的子函数,这个子函数的时间复杂度是O(n),所以总的时间复杂度是O(n3).由于我们是由外向内判断一个字符串是不是对称的,那么对于形如aba的字子串(b可以含有很多字符),我们判断aa相等后,还得判断b是否是对称;而在判断子串b的时候还得再判断一次,换句话说有很多的子串我们是重复判断的。那么我们能不能消除这种重复呢?、
【思 路2】根据上面的分析,我们很容易想到,如果我们从内向外比较字符,那么对于aba型的字符串,如果我们判断了b是对称的,只需要再左右各移一位就可以判断下一个字符串是否是对称的,这样我们就能避免重复;然而我们需要注意的是,对于原字符串中每一个字符有两种情况,一种是子串是以单个字符为中心对称分布的,换句话说,子串的长度是奇数;另一种情况是子串以两个字符串为中心,即子串的长度是偶数。至此我们就可以写出如下的代码:
测试结果如下:
效率分析:这种算法首先需要遍历一边字符串,外层为n,对于每一个字符,需要从该字符开始有中间到两边遍历一遍,因而总的时间复杂度是O(n2).
References:
程序员面试题精选100题:http://zhedahht.blog.163.com/blog/static/25411174201063105120425/
注:
1)本博客所有的代码环境编译均为win7+VC6。所有代码均经过博主上机调试。
2)博主python27对本博客文章享有版权,网络转载请注明出处http://www.cnblogs.com/python27/。对解题思路有任何建议,欢迎在评论中告知。
【思 路1】一看这题就是遍历!没错,我们最直观的往往也是最容易实现的,这里我们暂且不考虑效率的问题。我们的基本思路是:我们如果有一个判断一个字符串是不是对称的函数的话,我们就可以用这个子函数逐一检查原字符串中所有的字符串,然后输出长度最大的即可。
(1)怎样判断一个字符串是不是对称的字符串?我们可以用两个指针分别指向字符串的第一个字符和最后一个字符,判断是否相等,如果不等直接返回false,如果为真则接着比较下一对字符。(2)如果遍历遍历原字符串的所有子串,首先我们让一个指针从头至尾遍历,对于这个指针的每一个字符,我们在用另一个指针逐一指向它后面的每一个字符即可。好了,两个问题都解决了,我们可以写出如下的代码:
1 #include<iostream> 2 #include<string> 3 #include<cstring> 4 using namespace std; 5 6 /************************************************ 7 * 判断一个字符串是否是对称的 8 *************************************************/ 9 bool IsSymmetricalString(char* pstart,char* pend) 10 { 11 if(pstart == NULL || pend == NULL || pstart > pend) 12 return false; 13 14 while(pstart < pend) 15 { 16 if(*pstart != *pend) 17 { 18 return false; 19 } 20 else 21 { 22 pstart++; 23 pend--; 24 } 25 } 26 27 return true; 28 } 29 30 31 /************************************************* 32 * 求最大对称子串的长度 33 **************************************************/ 34 int MaxSymmetricalSubstringLenth(char *pstring) 35 { 36 if(pstring == NULL) 37 return 0; 38 39 int maxlength = 1; 40 41 int length = strlen(pstring); 42 char* pfirst = pstring; 43 while(pfirst < &pstring[length - 1]) 44 { 45 char* psecond = pfirst + 1; 46 while(psecond <= &pstring[length - 1]) 47 { 48 if(IsSymmetricalString(pfirst,psecond)) 49 { 50 int templength = psecond - pfirst + 1; 51 if(templength > maxlength) 52 { 53 maxlength = templength; 54 } 55 } 56 57 psecond++; 58 } 59 60 pfirst++; 61 } 62 63 return maxlength; 64 } 65 66 int main() 67 { 68 cout<<"Please Enter Your String(the length must <1000 ):"<<endl; 69 char* yourstring = new char[1000]; 70 cin>>yourstring; 71 72 cout<<"The Max Symmetrical SubString Length in Your String is:"<<endl; 73 cout<<MaxSymmetricalSubstringLenth(yourstring)<<endl; 74 75 return 0; 76 }
运行结果如下:
反思:我们现在来分析一下该算法的时间复杂度,首先遍历原字符串的所有子串有两个循环,这个时间复杂度是O(n2),我们在这两层循环之间有一个判断给定字符串是不是对称的子函数,这个子函数的时间复杂度是O(n),所以总的时间复杂度是O(n3).由于我们是由外向内判断一个字符串是不是对称的,那么对于形如aba的字子串(b可以含有很多字符),我们判断aa相等后,还得判断b是否是对称;而在判断子串b的时候还得再判断一次,换句话说有很多的子串我们是重复判断的。那么我们能不能消除这种重复呢?、
【思 路2】根据上面的分析,我们很容易想到,如果我们从内向外比较字符,那么对于aba型的字符串,如果我们判断了b是对称的,只需要再左右各移一位就可以判断下一个字符串是否是对称的,这样我们就能避免重复;然而我们需要注意的是,对于原字符串中每一个字符有两种情况,一种是子串是以单个字符为中心对称分布的,换句话说,子串的长度是奇数;另一种情况是子串以两个字符串为中心,即子串的长度是偶数。至此我们就可以写出如下的代码:
1 #include<iostream> 2 #include<string> 3 using namespace std; 4 5 /********************************************************************* 6 * 计算字符串最大对称子串的长度 7 *********************************************************************/ 8 int MaxSymmetricalSubstringLenth(char* pstring) 9 { 10 int maxlength = 1; 11 12 char* pchar = pstring + 1; 13 while(*pchar != '\0') 14 { 15 //以该字符串为中心,子串长度为奇数 16 char *pfirst = pchar - 1; 17 char *psecond = pchar + 1; 18 while(pfirst > pstring && psecond < &pstring[strlen(pstring) - 1] && *pfirst == *psecond) 19 { 20 pfirst--; 21 psecond++; 22 } 23 24 int templength = psecond - pfirst + 1; 25 if(templength > maxlength) 26 { 27 maxlength = templength; 28 } 29 30 31 //字该字符及之后的字符两个为中心,子串为偶数 32 pfirst = pchar - 1; 33 psecond = pchar; 34 while(pfirst > pstring && psecond < &pstring[strlen(pstring) - 1] && *pfirst == *psecond) 35 { 36 pfirst--; 37 psecond++; 38 } 39 40 templength = psecond - pfirst + 1; 41 if(templength > maxlength) 42 { 43 maxlength = templength; 44 } 45 46 pchar++; 47 } 48 49 return maxlength; 50 } 51 52 int main() 53 { 54 cout<<"Please Enter Your String:"<<endl; 55 char *yourstring = new char[1000]; 56 cin>>yourstring; 57 58 cout<<"The Max Symmetrical SubString Length is:"<<endl; 59 cout<<MaxSymmetricalSubstringLenth(yourstring)<<endl; 60 61 delete[] yourstring; 62 return 0; 63 }
测试结果如下:
效率分析:这种算法首先需要遍历一边字符串,外层为n,对于每一个字符,需要从该字符开始有中间到两边遍历一遍,因而总的时间复杂度是O(n2).
References:
程序员面试题精选100题:http://zhedahht.blog.163.com/blog/static/25411174201063105120425/
注:
1)本博客所有的代码环境编译均为win7+VC6。所有代码均经过博主上机调试。
2)博主python27对本博客文章享有版权,网络转载请注明出处http://www.cnblogs.com/python27/。对解题思路有任何建议,欢迎在评论中告知。
相关文章推荐
- 对称子字符串的最大长度
- 对称子字符串的最大长度
- 对称子字符串的最大长度
- 程序员面试100题之四十六,对称子字符串的最大长度
- 对称子字符串的最大长度
- 对称子字符串的最大长度
- 对称子字符串的最大长度
- 程序员面试题精选100题(46)-对称子字符串的最大长度
- 数据结构练习(34)对称子字符串的最大长度
- 程序员面试题精选100题(46)-对称子字符串的最大长度
- 程序员面试题精选100题(46)-对称子字符串的最大长度[算法]
- 对称子字符串的最大长度
- 对称子字符串的最大长度(程序员面试题精选100题)
- 对称子字符串的最大长度
- 面试训练对称子字符串的最大长度
- 求对称子字符串的最大长度
- 对称子字符串的最大长度
- 程序员面试题精选100题(46)-对称子字符串的最大长度
- 对称子字符串的最大长度
- 对称子字符串的最大长度