最长重复子串—后缀数组

2024-06-18 13:18

本文主要是介绍最长重复子串—后缀数组,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

知识点:
1. sort 使用时得注明:using namespace std;   或直接打 std::sort()  还得加上  #include <algorithm>
2. qort是qsort的升级版,如果能用sort尽量用sort,使用也比较简单,不像qsort还得自己去写 cmp 函数,
只要注明  使用的库函数就可以使用,参数只有两个(如果是普通用法)头指针和尾指针; 


3. 默认sort排序后是升序,如果想让他降序排列,可以使用自己编的cmp函数


bool compare(int a,int b){
 return a>b; //降序排列,如果改为return a<b,则为升序
}
sort(*a,*b,cmp);


4. compare 函数中对于double需要特别注意返回值的问题,
显然cmp返回的是一个整型,所以避免double返回小数而被丢失。


int cmp( const void *a , const void *b ){
return *(double *)a > *(double *)b ? 1 : -1;

}


分析:要求输出它及其首字符的位置。 例如字符串yyabcdabjcabceg,输出结果应该是abc和3。

  1.可以将上面字符串分解为,后缀数组形式。
substrs[0] =yyabcdabjcabceg;
substrs[1] =yabcdabjcabceg;
substrs[2] =abcdabjcabceg;
substrs[3] =bcdabjcabceg;
substrs[4] =cdabjcabceg;
substrs[5] =dabjcabceg;
substrs[6] =abjcabceg;
substrs[7] =bjcabceg;
substrs[8] =jcabceg;
substrs[9] =cabceg;
substrs[10]=abceg;
substrs[11]=bceg;
substrs[12]=ceg;
substrs[13]=eg;
substrs[14]=g;

  2.对这些字符串按照字典顺序排序,

  3.然后比较相邻字符串的前驱,找到最长的匹配项。


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>using namespace std;pair<int, string> fun(const string &str)
{vector<string> substrs;int maxcount = 1;unsigned int count = 0;string substr;int i, len = str.length();for (i = 0; i < len; i++)   // 得到所有的后缀子串{// basic_string substr(size_type pos = 0,size_type n = npos) const;// 从pos开始,截取n个字符组成的字符串。substrs.push_back(str.substr(i, len-i));}// 后缀树排序sort(substrs.begin(), substrs.end());// 比较相邻两个字符串公共序列string str1;string str2;vector<string>::iterator iter;for(iter = substrs.begin(); iter != substrs.end()-1; ){count = 0;str1 = *iter++;str2 = *iter;while(	count < str1.length() &&  count < str2.length()  &&  (str1.at(count) == str2.at(count))	)count++;if(count > maxcount){maxcount = count;substr = str1.substr(0, maxcount);}}substrs.clear();return make_pair(maxcount,substr);
}int main()
{string str;pair<int, string> rs;while (cin >> str){rs = fun(str);cout << rs.second << ':' << rs.first << endl;}return 0;
}

下面是另一种解题思路:
时间复杂度比上面介绍的要高,但是空间复杂度为O(1).时间换空间。
思路:对源字符串所有后缀的所有子串,从每一个后缀的最长子串开始,
分别从前向和后向开始在源字符串中查找匹配的子串,
若两次查找位置不一致则说明存在重复的长度最长的字串,并返回前向查找时的位置。
e.g. string = “abcedfghiabckl‘,当使用子串”abc“在源字符串中分别前向和后向匹配时,

找到的位置分别为pos1=0, pos2 = 9.

#include <iostream>
#include <string>
using namespace std;
int main()
{string str,tep;cin>>str;cout<<"length=="<<str.length()<<endl;for (int i = str.length()-1; i>=1; i--){for (int j = 0; j < str.length(); j++){// 如果没有这句的约束,那么结果错误。// 这句话使得每次得到的tep的长度是i,即满足从大到小取字符串。if (j + i <= str.length()){size_t t = 0;size_t num = 0;tep = str.substr(j, i); // 从大到小取字串。i是截取的字符串的长度,先截取最长的,再截取次长的t = str.find(tep);		// 正序查找num = str.rfind(tep);	// 逆序查找// 如果两次查找的位置不一样,说明存在重复字串。if (t != num)			// 满足条件就输出,因为是从最长的字符串开始截取。{cout<<tep<<" "<<t<<endl;return 0;}}}}return 0;
}

这篇关于最长重复子串—后缀数组的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1072100

相关文章

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

MySQL中查找重复值的实现

《MySQL中查找重复值的实现》查找重复值是一项常见需求,比如在数据清理、数据分析、数据质量检查等场景下,我们常常需要找出表中某列或多列的重复值,具有一定的参考价值,感兴趣的可以了解一下... 目录技术背景实现步骤方法一:使用GROUP BY和HAVING子句方法二:仅返回重复值方法三:返回完整记录方法四:

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

XML重复查询一条Sql语句的解决方法

《XML重复查询一条Sql语句的解决方法》文章分析了XML重复查询与日志失效问题,指出因DTO缺少@Data注解导致日志无法格式化、空指针风险及参数穿透,进而引发性能灾难,解决方案为在Controll... 目录一、核心问题:从SQL重复执行到日志失效二、根因剖析:DTO断裂引发的级联故障三、解决方案:修复

SpringBoot+Redis防止接口重复提交问题

《SpringBoot+Redis防止接口重复提交问题》:本文主要介绍SpringBoot+Redis防止接口重复提交问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录前言实现思路代码示例测试总结前言在项目的使用使用过程中,经常会出现某些操作在短时间内频繁提交。例

MySQL JSON 查询中的对象与数组技巧及查询示例

《MySQLJSON查询中的对象与数组技巧及查询示例》MySQL中JSON对象和JSON数组查询的详细介绍及带有WHERE条件的查询示例,本文给大家介绍的非常详细,mysqljson查询示例相关知... 目录jsON 对象查询1. JSON_CONTAINS2. JSON_EXTRACT3. JSON_TA

C#之List集合去重复对象的实现方法

《C#之List集合去重复对象的实现方法》:本文主要介绍C#之List集合去重复对象的实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C# List集合去重复对象方法1、测试数据2、测试数据3、知识点补充总结C# List集合去重复对象方法1、测试数据

使用C#删除Excel表格中的重复行数据的代码详解

《使用C#删除Excel表格中的重复行数据的代码详解》重复行是指在Excel表格中完全相同的多行数据,删除这些重复行至关重要,因为它们不仅会干扰数据分析,还可能导致错误的决策和结论,所以本文给大家介绍... 目录简介使用工具C# 删除Excel工作表中的重复行语法工作原理实现代码C# 删除指定Excel单元

JAVA数组中五种常见排序方法整理汇总

《JAVA数组中五种常见排序方法整理汇总》本文给大家分享五种常用的Java数组排序方法整理,每种方法结合示例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录前言:法一:Arrays.sort()法二:冒泡排序法三:选择排序法四:反转排序法五:直接插入排序前言:几种常用的Java数组排序