题目:
给定一个字符串,求出其最长的重复子串(最长重复子串可以重叠)。
如字符串abcdabcabcd,其最长的重复子串为abcd;
如字符串abcdabcda,其最长的重复子串为abcda。
算法思想:
对字符串生成相应的后缀数组,再对其排序,排序后依次检测相邻两个字符串的公共前缀,时间复杂度为O(N^2*logN)。
程序如下:
#include<iostream>
using namespace std;
#define MAX 256
/* 定义全局变量 */
char str[MAX];
char *suffix_array[MAX];// 对于长度为n的字符串,其后缀数组的长度亦为n(存放n个后缀字符串)
/* 初始化字符串与其后缀数组 */
void suffix(char *str, char **suffix_array)
{
int i = 0;
char ch;
while((ch = getchar()) != '\n')
{
str[i] = ch;
suffix_array[i] = &str[i];
i++;
}
str[i] = '\0';
}
/* 冒泡排序 */
void bubbleSort(char **suffix_array, int n)
{
...
}
/* 快速排序 */
void quickSort(char **suffix_array, int left, int right)
{
...
}
/* 返回两个字符串公共前缀的最大长度 */
int compLen(char *str1, char *str2)
{
int len = 0;
while (*str1 && *str1 == *str2)
{
len++;
str1++;
str2++;
}
return len;
}
/* 由排序后的后缀数组,求得最长的重复子串的长度 */
char* assignStrWithMaxLen(char *dest, char **sorted_suffix_array, int n)
{
int max = 0;
int beginIndex = -1;
for (int i = 0; i < n - 1; i++)
{
int tmp = compLen(sorted_suffix_array[i], sorted_suffix_array[i + 1]);
if (tmp > max)
{
max = tmp;
beginIndex = i;
}
}
strncpy(dest, sorted_suffix_array[beginIndex], max);
return dest;
}
int main()
{
suffix(str, suffix_array);
int n = strlen(str);// 字符串字符的个数,也是后缀字符串的个数
/* 对后缀数组进行排序 */
//bubbleSort(suffix_array, n);
quickSort(suffix_array, 0, n - 1);
char dest[MAX] = {'\0'};
assignStrWithMaxLen(dest, suffix_array, n);
cout << dest << endl;
return 0;
}
复习排序算法:
/* 冒泡排序 */
void bubbleSort(char **suffix_array, int n)
{
for (int i = 0; i < n; i++)// i表示已在最终位置的元素的个数
{
int flag = 1;
for (int j = 0; j + 1 < n - i; j++)// 后i个元素已有序,只需前(n-i)个元素比较
{
if (strcmp(suffix_array[j], suffix_array[j + 1]) > 0)
{
swap(suffix_array[j], suffix_array[j + 1]);
flag = 0;
}
}
if (flag == 1)
{
break;
}
}
}
/* 快速排序 */
void quickSort(char **suffix_array, int left, int right)
{
if (left < right)
{
char *pivot = suffix_array[left];
int i = left, j = right;
while (i < j)
{
while (i < j && strcmp(suffix_array[j], pivot) >= 0)
{
j--;
}
if (i < j)
{
swap(suffix_array[i++], suffix_array[j]);
}
while (i < j && strcmp(suffix_array[i], pivot) <= 0)
{
i++;
}
if (i < j)
{
swap(suffix_array[i], suffix_array[j--]);
}
}
suffix_array[i] = pivot;// 此时i=j
quickSort(suffix_array, left, i - 1);
quickSort(suffix_array, i + 1, right);
}
}
void swap(char *&ptr1, char *&ptr2)
{
char *tmp = ptr1;
ptr1 = ptr2;
ptr2 = tmp;
}
分享到:
相关推荐
总结来说,解决“求字符串中出现相同且长度最长字符串”的问题,我们可以运用滑动窗口、哈希映射或动态规划等技术。在实际编程中,应根据数据规模和性能要求选择合适的方法。对于给定的示例字符串,最终输出应为...
本问题聚焦于找出字符串中的最长重复子串及其出现位置,这是一个典型的字符串处理任务,具有较高的实用价值。 最长重复子串是指在一个字符串中,连续重复出现次数最多的子串。解决这个问题通常需要使用滑动窗口、...
在计算机科学领域,“求串中最长重复子串”是一个常见的字符串处理问题。假设有一个字符串S,我们的任务是找出其中最长的重复子串,即在S中至少出现两次的最长连续子序列。这个问题不仅涉及到字符串匹配的基本概念,...
为找到最长的重复子字符串,我们需要在统计频率的同时,记录下当前找到的最长重复子串及其长度。每次更新最长子串时,不仅要考虑长度,还需要确保其在字符串中出现了至少两次。 这里可以采用两种方法实现: 1. **...
最长公共子序列(Longest Common Subsequence,LCS)是计算机科学中一种经典的字符串问题,主要涉及算法设计和分析。它的目标是找到两个给定序列(通常为字符串)的最长子序列,该子序列在原序列中不需连续,但必须...
根据给定的文件信息,本篇文章将详细解析“给定一个字符串,求出其最长的重复子串”这一算法问题。此题目源自于腾讯2011年10月15日的校园招聘笔试,主要考察应试者对字符串处理、排序及模式匹配等算法的理解与应用...
本篇文章主要探讨了如何在给定的字符串中找到最长的重复子串。例如,在字符串 "t1t1" 中,最长重复子串为 "t1";而在 "cabcabca" 中,最长重复子串可以是 "cab"、"abc" 或者 "bca"。 #### 技术实现思路 为了找到...
标题 "寻找字符串中不包含重复字符的最长子串" 指向的是一个经典的计算机科学问题,主要涉及字符串处理和算法设计。这个问题的目标是找出给定字符串中的最长子串,这个子串中的所有字符都不重复。这是一个在编程面试...
对于字符串最长回文子串的问题,我们可以创建一个与原字符串大小相同的二维数组`dp`,其中`dp[i][j]`表示字符串从索引`i`到`j`的子串是否是回文。 初始化`dp`数组,当`i == j`时,单个字符一定是回文,所以`dp[i][i...
本文实例讲述了C语言求两个字符串的最长公共子串的方法。分享给大家供大家参考。具体实现方法如下: #include "stdio.h" #include "string.h" #include "stdlib.h" void getCommon(char str1[],char str2[],char * ...
【Python求两个字符串最长公共子序列】 在编程领域,字符串操作是常见任务之一,而寻找两个字符串的最长公共子序列(LCS)是其中的一个经典问题。LCS是指两个字符串中都出现过的最长的连续子序列,但不考虑字符在...
main_str = "这是一个测试字符串,包含子字符串重复多次" sub_str = "字符串" print(count_substring(main_str, sub_str)) ``` 这种方法适用于简单的场景,但如果子字符串是正则表达式或者需要考虑重叠情况时,我们...
剑指offer.48
找出一个字符串中出现次数最多的子字符串,并返回重复次数。使用java编写
查找字符串中重复的子字符串积重复的次数 在软件网络技术领域中,查找字符串中重复的子字符串积重复的次数是一个常见的问题,本文将通过 Java 语言实现这个功能,并对其中的知识点进行详细的解释。 知识点一:字符...
"文本重复字符串查找"是其中一个重要的子任务,它的目的是找出文本中出现多次的相同字符串。这个工具显然允许用户进行定制化的搜索,比如设置重复字符串的最小长度以及排除某些特定的字符串。这种功能对于识别文本中...
这个问题的核心在于找到一个字符串与其反转后的最长相同子序列。我们可以通过动态规划或者双指针等方法来解决这个问题。下面将详细介绍如何用Java实现这一功能。 首先,我们需要明确几个概念: 1. **字符串**:在...
该函数的语法为 Replace(expression, find, replacewith[, compare[, count[, start]]]),其中 expression 为要替换的字符串,find 为要替换的子字符串,replacewith 为要替换的新子字符串,compare 为比较方式(可...