【字符串问题】求一个字符串中重复出现的最长的子串
2013-09-14 15:34:16
用后缀数组求一个字符串中重复出现的最长的子串。
- 用C++中的string类可以很方便地进行操作,需将后缀数组保存在vector<string>,如下面代码中的string版本所示,但这样就会因为<string>有很大的开销;
- 直接用字符指针指向后缀字符串的首地址,可以节省很大的空间,如下面代码中的char *版本所示.
- 注意使用char *版本时,用qsort函数最后缀字符串数组排序,需要提供comp函数,该函数的写法如下:
1 int pStrcmp(const void *p,const void *q) 2 { 3 return ( strcmp( *(char **)p , *(char **)q ) ); 4 }
更多关于该函数的说明,详见博文http://www.cnblogs.com/youngforever/articles/3321469.html。
代码(string版本):
1 #include <iostream> 2 #include <cassert> 3 #include <string> //用string类模板,必须包含该头文件 4 #include <vector> //用vector模板,必须包含该头文件 5 #include <algorithm> //用sort函数,必须包含该头文件 6 using namespace std; 7 8 //获取两个字符串的最长公共子串 9 size_t GetLCS(const string &str1,const string &str2) 10 { 11 size_t len1 = str1.length(); 12 size_t len2 = str2.length(); 13 14 size_t end = len1 < len2 ? len1 : len2; 15 16 size_t index = 0; 17 size_t commenLen = 0; 18 19 for (index = 0;index < end;++index) 20 { 21 if (str1.at(index) == str2.at(index)) 22 { 23 ++commenLen; 24 } 25 else 26 { 27 break; 28 } 29 } 30 31 return commenLen; 32 } 33 34 //获取字符串中重复出现且最长的子串 35 size_t FindLongeStringApearTwice(const string &srcStr,string &subStr) 36 { 37 vector<string> vecStr; 38 39 size_t index; 40 size_t end = srcStr.length(); 41 42 string tmpStr; 43 size_t tmpLen = 0; 44 size_t maxLen = 0; 45 46 for ( index = 0;index < end;++index) //生成后缀数组 47 { 48 tmpStr = srcStr.substr(index,(end - 1 - index)); 49 vecStr.push_back(tmpStr); 50 //tmpStr.clear(); //此处的清楚是不必要的,可以删去 51 } 52 53 sort(vecStr.begin(),vecStr.end()); //对后缀字符串数组排序 54 55 vector<string>::iterator iter; 56 57 for (iter = vecStr.begin();(iter + 1) != vecStr.end();++iter) //求相邻string的LCS 58 { 59 tmpLen = GetLCS(*iter,*(iter + 1)); 60 61 if(tmpLen > maxLen) 62 { 63 maxLen = tmpLen; 64 subStr = (*iter).substr(0,maxLen); 65 } 66 } 67 68 return maxLen; 69 } 70 71 72 73 74 //测试FindLongeStringApearTwice 75 void TestDriver() 76 { 77 string strArray[] = {"0123456","yyabcdabjcabceg","abcbcbcabc","hello,li mei! hello,li lei!"}; 78 size_t arrayLength = 4; 79 80 string srcStr; 81 string subStr; 82 size_t maxLen = 0; 83 84 for (size_t index = 0;index < arrayLength;++index) 85 { 86 //srcStr.clear(); //此处的清楚是不必要的,可以删去 87 srcStr = strArray[index]; 88 maxLen = FindLongeStringApearTwice(srcStr,subStr); 89 90 cout<<"the source string is : "<<srcStr<<endl; 91 cout<<"the longest sub string is : "<<subStr<<endl; 92 cout<<"the max length is : "<<maxLen<<endl; 93 cout<<endl; 94 } 95 } 96 97 int main() 98 { 99 TestDriver(); 100 return 0; 101 }
代码(char *版本):
1 #include <iostream> 2 #include <cassert> 3 #include <string> 4 #include <vector> 5 #include <algorithm> 6 using namespace std; 7 8 size_t GetLCS(const char *str1,const char *str2) 9 { 10 assert(str1 != NULL && str2 != NULL); 11 12 size_t len1 = strlen(str1); 13 size_t len2 = strlen(str2); 14 15 size_t end = len1 < len2 ? len1 : len2; 16 17 size_t index = 0; 18 size_t commenLen = 0; 19 20 for (index = 0;index < end;++index) 21 { 22 if ( *(str1 + index) == *(str2 + index) ) 23 { 24 ++commenLen; 25 } 26 else 27 { 28 break; 29 } 30 } 31 32 return commenLen; 33 } 34 35 typedef char * pCHAR; 36 37 int pStrcmp(const void *p,const void *q) 38 { 39 return ( strcmp( *(char **)p , *(char **)q ) ); 40 } 41 42 void DisplayString(const char *pStr) 43 { 44 size_t index = 0; 45 46 while (*(pStr + index)) 47 { 48 cout<<*(pStr + index); 49 ++index; 50 } 51 cout<<endl; 52 } 53 54 size_t FindLongestStringApearTwice(const char *pSrcStr,char *&pSubStr) 55 { 56 assert(pSrcStr != NULL && pSubStr != NULL); 57 58 const size_t lenOfSrcStr = strlen(pSrcStr); 59 pCHAR *pSuffixArray = new pCHAR[lenOfSrcStr]; 60 61 size_t index; 62 size_t end = strlen(pSrcStr); 63 64 size_t tmpLen = 0; 65 size_t maxLen = 0; 66 67 for ( index = 0;index < end;++index) 68 { 69 pSuffixArray[index] = (char *)pSrcStr + index; 70 //DisplayString(pSuffixArray[index]); 71 } 72 73 qsort(pSuffixArray,lenOfSrcStr,sizeof(pCHAR),pStrcmp); 74 /* 75 for ( index = 0;index < end;++index ) 76 { 77 DisplayString(pSuffixArray[index]); 78 }*/ 79 80 for (index = 0;index + 1 < end;++index) 81 { 82 tmpLen = GetLCS(pSuffixArray[index],pSuffixArray[index + 1]); 83 84 if(tmpLen > maxLen) 85 { 86 maxLen = tmpLen; 87 pSubStr = pSuffixArray[index]; 88 } 89 } 90 91 return maxLen; 92 } 93 94 95 void TestDriver() 96 { 97 pCHAR strArray[] = {"0123456","yyabcdabjcabceg","abcbcbcabc","hello,li mei! hello,li lei!"}; 98 size_t arrayLength = 4; 99 100 pCHAR srcStr; 101 pCHAR subStr; 102 size_t maxLen = 0; 103 104 for (size_t index = 0;index < arrayLength;++index) 105 { 106 srcStr = strArray[index]; 107 maxLen = FindLongestStringApearTwice(srcStr,subStr); 108 109 cout<<"the source string is : "<<srcStr<<endl; 110 cout<<"the longest sub string is : "; 111 112 for (size_t i = 0;i < maxLen;++i) 113 { 114 cout<<*(subStr + i); 115 } 116 cout<<endl; 117 118 cout<<"the max length is : "<<maxLen<<endl; 119 cout<<endl; 120 } 121 } 122 123 124 int main() 125 { 126 TestDriver(); 127 return 0; 128 }
测试结果:
the source string is : 0123456 the longest sub string is : the max length is : 0the source string is : yyabcdabjcabceg the longest sub string is : abc the max length is : 3the source string is : abcbcbcabc the longest sub string is : bcbc the max length is : 4the source string is : hello,li mei! hello,li lei! the longest sub string is : hello,li the max length is : 9请按任意键继续. . .
【字符串问题】求一个字符串中重复出现的最长的子串相关推荐
- 求一个字符串中连续出现的次数最多的子串
求一个字符串中连续出现的次数最多的子串.例如字符串"abababc",最多连续出现的为ab,连续出现三次.要和求一个字符串中的最长重复子串区分开来,还是上面的字符串,那么最长的重复 ...
- 求一个字符串中连续出现次数最多的子串
http://blog.csdn.net/imcdragon/article/details/6838565解答二 http://hi.baidu.com/icyday315/item/040aada ...
- 【算法题】求一个字符串的最长不重复子串
[题目描述] 求一个字符串的最长不重复子串.比如:给定"abcabcbb"的答案是"abc",长度是3:给定"bbbbb"的答案是" ...
- 写一个函数,求一个字符串的长度,在main 函数中输入字符串,并输出其长度。
// 写一个函数,求一个字符串的长度,在main 函数中输入字符串,并输出其长度. #include <stdio.h> main() { int len; char*str[20]; ...
- 习题 8.6 写一函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度。
C程序设计(第四版) 谭浩强 习题8.6 个人设计 习题 8.6 写一函数,求一个字符串的长度.在main函数中输入字符串,并输出其长度. 代码块: 方法1: #include <stdio.h ...
- 写一个函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度
写一个函数,求一个字符串的长度.在main函数中输入字符串,并输出其长度 代码如下: #include<stdio.h> int len(char *p); int main() {int ...
- 题8.6:写一函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度。
题目 本题是谭浩强<C程序设计课后习题>题8.6. 题目: 写一函数,求一个字符串的长度.在main函数中输入字符串,并输出其长度. 以下是本篇文章正文内容,欢迎朋友们进行指正,一起探讨, ...
- 写一函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度。
写一函数,求一个字符串的长度.在main函数中输入字符串,并输出其长度. 解题思路: 字符串以\0作为结尾,则从第一个字符开始向后移动遇到\0认为字符串结束. 答案: #include <std ...
- Java实现统计某字符串在另一个字符串中出现的次数
面试时会经常考这样的题目,估计也不让使用正则表达式.还好这个算法还算简单,不过在草稿纸上写难免会出现运行异常,好吧,面试官赢了,乃们屌丝就实实在在的把代码码出来吧. 谢谢"心扉"对 ...
最新文章
- 2020-09-27 What is Sector-Bounded Nonlinearities?
- SQLSERVER 执行过的语句查询
- .net 用户控件ascx.cs注册js脚本代码无效果
- 微信小程序中处理 获取用户地址的回调
- 《云栖社区2017年度内容特辑》新鲜出炉!800+份大会PPT、20+技术专题、100+话题...快抱走!...
- win10计算机安全模式怎么,Win10进入安全模式的多种方法
- 【笔记】ThreadFactory自定义线程名前缀
- Win11系统一些功能修改并不令人满意,盘点不尽人意之处
- 程序员只能在一线城市么?
- UVA10142/PC110108Australian Voting
- jQuery获取或设置元素的属性值prop/attr
- 2020华为软挑热身赛代码开源-思路大起底(华为软件精英挑战赛编程闯关)
- [CTF] 每日一题汇总
- vue中引入高德地图
- Node.js学习(express+node项目实战)
- rcar-du display timing generation
- 优秀java实习报告范文5篇
- 【C++】浮点数的std::fixed、std::setprecision()、std::setw()用法
- 【重磅】Deepmind出品-自动学习并生成图像
- php array_clunm,Python 玩转图像格式转换操作
热门文章
- (一)nodejs循序渐进-nodejs环境安装(基础篇)
- thinkphp的快捷方法实例化对象
- 《深入理解JVM.2nd》笔记(一):走进Java
- 密码学专题 相关概念的解析 对称算法|算法的安全性|非对称算法存在的问题|单向散列函数|数字签名的弊端|密钥交换
- 面试中如何剔除“鱼目混珠”程序员?
- 盘点大数据的十大发展方向,Scale-out将成主流
- 阶乘的精确值 大数问题
- 麻雀虽小,五脏俱全:分析CVS活动情况的小工具(有源码供学习)
- Docker 方式安装 gitlab ( 阿里云ECS )
- FreeSql (十)更新数据