【字符串问题】求一个字符串中重复出现的最长的子串

2013-09-14 15:34:16

用后缀数组求一个字符串中重复出现的最长的子串。

  1. 用C++中的string类可以很方便地进行操作,需将后缀数组保存在vector<string>,如下面代码中的string版本所示,但这样就会因为<string>有很大的开销;
  2. 直接用字符指针指向后缀字符串的首地址,可以节省很大的空间,如下面代码中的char *版本所示.
  3. 注意使用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请按任意键继续. . .

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/462111.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于scanf和的问题

简单地说&#xff0c;如果使用scanf函数把一个字符串读进一个字符数组中&#xff0c;不要使用&&#xff1b;读取其他基本变量类型时&#xff0c;在变量名之前添加&。或者说&#xff0c;字符串名字本身就是一个地址了&#xff0c;所以不用取地址符。 如以下代码&#xf…

Oracle lower() Upper()函数

即将某字段信息中的字母转成小写、大写的方法。 将 user表里的user_name字段信息中含有字母的全部转成大写的方法&#xff1a; update user set  user_nameUpper(user_name) 同理得到将 user表里的user_name字段信息中含有字母的全部转成小写的方法&#xff1a; update user …

【作品】超级玛丽射击版

【下载地址】稍后上传 【以下内容摘自试验报告&#xff0c;可能狗屁不通&#xff0c;尽情谅解】 &#xff0d;游戏介绍: 简单的射击游戏,键盘控制动作[角色的移动,跳跃等],鼠标控制攻击的位置方向, 单击鼠标即射击,同时可以设置游戏规定时间,时间到则结束游戏. &#xff0d;游戏…

嵌入式系统Linux内核开发工程师必须掌握的三十道题

嵌入式系统Linux内核开发工程师必须掌握的三十道题 如果你能正确回答以下问题并理解相关知识点原理&#xff0c;那么你就可以算得上是基本合格的Linux内核开发工程师&#xff0c;试试看&#xff01; 1) Linux中主要有哪几种内核锁&#xff1f; Linux的内核锁主要是自旋锁和信号…

MySQL锁的用法之行级锁

2019独角兽企业重金招聘Python工程师标准>>> 行级锁是MySQL中粒度最小的一种锁&#xff0c;他能大大减少数据库操作的冲突。但是粒度越小&#xff0c;实现的成本也越高。MYISAM引擎只支持表级锁&#xff0c;而INNODB引擎能够支持行级锁&#xff0c;下面的内容也是针…

matlab中二维插值函数interp2的使用

下面是一段产生log-normal分布的代码&#xff0c;以此进行说明。 clear all; clc; for t1:100Traffic(t) curve(t); end MaxTraffic max(Traffic); w 0.2; Wmax 2*pi*w/3000; x[0:10:300]; y[0:10:300]; Nxlength(x); Nylength(y); Sigma 0.53; t 0&#xff1b; M 10*cu…

8天玩转并行开发——第五天 同步机制(下)

承接上一篇&#xff0c;我们继续说下.net4.0中的同步机制&#xff0c;是的&#xff0c;当出现了并行计算的时候&#xff0c;轻量级别的同步机制应运而生&#xff0c;在信号量这一块 出现了一系列的轻量级&#xff0c;今天继续介绍下面的3个信号量 CountdownEvent&#xff0c;Se…

hive中not in优化

比如&#xff1a;A,B两表&#xff0c;找到ID字段中&#xff0c;存在A表&#xff0c;但不存在B表的数据。A表共13w&#xff0c;去重后3w,B表共2W&#xff0c;且有索引方法一not in&#xff0c;易理解&#xff0c;效率低&#xff0c;时间&#xff1a;1.395sselect distinct A.id …

Quartz 2D编程笔记

当我们需要在一个图形上下文中构建一个路径时&#xff0c;我们需要调用CGContextBeginPath来标记Quartz。然后&#xff0c;我们调用函数CGContextMovePoint来设置每一个图形或子路径的起始点。在构建起始点后&#xff0c;我们可以添加直线、弧、曲线。记住如下规则&#xff1a;…

bitmap算法

博文转载于http://www.cnblogs.com/dyllove98/archive/2013/07/26/3217741.html概述所谓bitmap就是用一个bit位来标记某个元素对应的value&#xff0c;而key即是这个元素。由于采用bit为单位来存储数据&#xff0c;因此在可以大大的节省存储空间算法思想 32位机器上&#xff0c…

Ubuntu下如何解压缩zip,tar,tar.gz,tar.bz2文件

tar解包&#xff1a;tar xvf FileName.tar打包&#xff1a;tar cvf FileName.tar DirName&#xff08;注&#xff1a;tar是打包&#xff0c;不是压缩&#xff01;&#xff09;———————————————.gz解压1&#xff1a;gunzip FileName.gz解压2&#xff1a;gzip -d F…

SELECT INTO 和 INSERT INTO SELECT 两种表复制语句

Insert是T-sql中常用语句&#xff0c;Insert INTO table(field1,field2,...) values(value1,value2,...)这种形式的在应用程序开发中必不可少。但我们在开发、测试过程中&#xff0c;经常会遇到需要表复制的情况&#xff0c;如将一个table1的数据的部分字段复制到table2中&…

向前插入迭代器

**向前插入迭代器&#xff0c;是架构在具有push_front向前插入函数的序列容器&#xff08;比如deque list&#xff09;上的输出迭代器&#xff0c;可以利用*改迭代器提供的“”&#xff0c;“*”&#xff0c;“”以“*fii9;”的类似的形式完成容器元素的赋值。**其中“*”和&qu…

Discuz!X集群部署的系统方案和改造方式讨论

多WEB部署时&#xff0c;面临的核心问题是WEB服务器间的数据共享和同步。就数据存储的方式而言&#xff0c;Discuz数据包含两部分&#xff0c;一部分存储在MySQL数据库中&#xff08;用户、帖子等文本类、结构化的数据&#xff09;&#xff0c;一部分存储为文件&#xff08;附件…

static和extern的用法总结

static用法见&#xff1a; 1、http://www.cnblogs.com/yezhenhan/archive/2011/10/31/2229724.html2、http://www.52rd.com/Blog/Detail_RD.Blog_imjacob_5297.htmlextern用法&#xff1a;1、http://blog.csdn.net/cameracanon/article/details/40614192、http://blog.csdn.net…

给vmware虚拟机中的ubuntu 14.04扩大磁盘分区

一.先取得root 权限 $ su - root Password: su: Authentication failure Sorry. 这时候输入 $ sudo passwd root Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully 这时候就可以进入根目录了。 二.具体安装步骤 用VMware安装了一…

个人管理 - 书籍推荐(待读)

在《个人管理 &#xff0d; 书籍推荐&#xff08;已读&#xff09;》中推荐了一些书籍&#xff0c;有些人从中选取了一些&#xff0c;但其实还有很多好书我还没有读&#xff0c;为了给大家更多选择&#xff0c;我把我欠下的书债也贴上来。由于豆瓣还没有提供书列表的功能&#…

windows7旗舰版序列号[经测试,第一枚即可完成升级!]

windows7旗舰版序列号[经测试&#xff0c;第一枚即可完成升级!] 第一枚&#xff1a;TFP9Y-VCY3P-VVH3T-8XXCC-MF4YK 第二枚&#xff1a;KH2J9-PC326-T44D4-39H6V-TVPBY 第三枚&#xff1a;C4M9W-WPRDG-QBB3F-VM9K8-KDQ9Y 第四枚&#xff1a;J783Y-JKQWR-677Q8-KCXTF-BHWGC 第五…

Node.js用6行代码1个JS文件搭建一个HTTP静态服务器

2019独角兽企业重金招聘Python工程师标准>>> Node.js宣言&#xff1a;Node.js is a platform built on Chromes JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes i…

制作jffs2根文件系统

一、制作mkfs.jffs2工具 首先得准备好两个软件包 &#xff0c;一个是MTD设备的工具包&#xff0c;另一个是zlib压缩包&#xff0c;在这我的MTD设备工具包为mtd-snapshot-20050519.tart.tar&#xff0c;zlib压缩包是zlib-1.2.3.tar.tar。 步骤&#xff1a; &#xff08;1&#…