求字符串中重复出现的最长字串

求字符串中重复出现的最长字串

例如字符串:drgabcifrabcsdrrs中,最长公共字串是:abc

方法:利用后缀树来求。

字符串的后缀树有如下:

drgabcifrabcsdrrs

rgabcifrabcsdrrs

gabcifrabcsdrrs

abcifrabcsdrrs---------s1

..............

rabcsdrrs

abcsdrrs-----------s2

...............

我们求的这些后缀字符串中,某2个串的最长公共前缀就是想要的答案。比如s1和s2的最长公共前缀:abc

我们为了简化运算,讲后缀字符串排序,这样前缀相同的就会排在相邻的位置上。

代码如下:

 

 

 

#include<iostream>
#include<string>
using namespace std;

int commonStr(string str1,string str2)//求两个字符串最长公共前缀长度
{
    int len = (str1.length()>str2.length())?str2.length():str1.length();
    int i=0;
    while(i<len && str1[i]==str2[i])
                i++;
    return i;
}

void maxLen(string str,string &key)//求字符串str的最长重复字串,key是用来存放前缀的
{
    int len = str.length();
    string *sub= new string[len];//定义一个字符串数据存放后缀字符串
    for(int i=0;i<len;i++)
    {
            sub[i] = str.substr(i,len-i);
    }
    sort(sub,sub+len);//对后缀字符串进行排序
    int max = 1;
    for(int i = 1;i<len;i++)
    {
            int count = commonStr(sub[i],sub[i-1]);//计算相邻的字符串的公共前缀长度
            if(max<count)//如果当前长度大于最大长度,那么更新max和key
            {
                         key = sub[i].substr(0,count);
                         max = count;
            }
    }
}
int main()
{
    string str = "yyabcdabjcabcdg";
    string key = "abc";
    maxLen(str,key);
    cout<<key<<endl;
    getchar();
    return 0;
}

 

 

 

 

 

在JavaScript,找出字符串重复最长的子可以通过多种算法实现,其一个高效的方法是使用动态规划。下面提供一个基于动态规划的示例实现: ```javascript function longestDupSubstring(S) { const MOD = 1000000007; const base = 26; // 字母的总数 let n = S.length; let maxLen = 0; // 最长相等子的长度 let startIndex = 0; // 最长相等子的起始索引 let hash = 0; // 当前子的哈希值 let basePower = 1; // base的幂,用于计算新的哈希值 // 计算最大的base的n-1次幂 for (let i = 0; i < n; i++) { basePower = (basePower * base) % MOD; } // 计算字符串的哈希值 for (let i = 0; i < n; i++) { hash = (hash * base + S.charCodeAt(i) - 'a'.charCodeAt(0)) % MOD; } // 存储每个字符出现的哈希值和对应的索引 const indexMap = new Map([[hash, 0]]); // 使用滚动哈希来计算子的哈希值 for (let i = 1; i < n; i++) { hash = (hash * base + S.charCodeAt(i) - 'a'.charCodeAt(0)) % MOD; if (indexMap.has(hash)) { let j = indexMap.get(hash); if (S.slice(j, i) === S.slice(j + maxLen, i + maxLen)) { startIndex = j; maxLen = i - j; } } else { indexMap.set(hash, i); } } // 返回最长重复 return S.slice(startIndex, startIndex + maxLen); } // 测试用例 console.log(longestDupSubstring("banana")); // 应该返回 "an" ``` 这段代码首先计算了字符串的哈希值,然后使用一个哈希表来存储出现过的子哈希值及其起始索引。通过滚动窗口的方法,我们可以在O(n)的时间复杂度内找到最长重复
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值