Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 最长最大重复子串_C++_String_Algorithm_Substring_Suffix Tree - Fatal编程技术网

C++ 最长最大重复子串

C++ 最长最大重复子串,c++,string,algorithm,substring,suffix-tree,C++,String,Algorithm,Substring,Suffix Tree,子字符串的长度可以是1,2,3。。。 我试图解决的问题是找到出现次数最多的子字符串。因此,它基本上分解为寻找具有最大频率的角色。 然而,我发现使用O(n)中的后缀树可以找到最长的重复子字符串。 但是,后缀树返回保持长度优先的子字符串。 我想找到出现次数最多的子串,在这些子串中我想找到最长的一个。 例如: 我试图通过在两个索引I和j之间生成子字符串来解决这个问题。之后,使用在O(n)中运行的Z算法来查找每种情况下这些子字符串的出现情况。然而,总复杂度为O(n^3) 我的O(n^3)代码 map-m

子字符串的长度可以是1,2,3。。。 我试图解决的问题是找到出现次数最多的子字符串。因此,它基本上分解为寻找具有最大频率的角色。 然而,我发现使用O(n)中的后缀树可以找到最长的重复子字符串。 但是,后缀树返回保持长度优先的子字符串。 我想找到出现次数最多的子串,在这些子串中我想找到最长的一个。 例如:


我试图通过在两个索引I和j之间生成子字符串来解决这个问题。之后,使用在O(n)中运行的Z算法来查找每种情况下这些子字符串的出现情况。然而,总复杂度为O(n^3)

我的O(n^3)代码

map-m;
字符串s;cin>>s;

对于(ll i=0;i单个字符计为子字符串,因此最大重复子字符串的出现频率必须等于字符串中最常见的字符

这意味着最大重复子字符串中的每个字符在字符串中只能出现一次,因为如果出现多次,则该字符本身将成为最大重复字符串。例如,子字符串“dad”在字符串“dadxdaydadzdaydad”中出现5次,但子字符串“d”发生10次

它们还必须每次以相同的顺序出现(否则单个字符的频率将高于子字符串,并且是最大重复子字符串本身)。它们也不能单独出现在子字符串中(否则它们将再次成为最大重复子字符串)

因此,最大重复子字符串必须由相同频率出现的字符的子集(或全部)组成

我们可以很容易地通过一次遍历字符串并对其进行计数来确定这些字符是哪些字符。我们还可以通过跟踪每个字符前后出现的字符来推断哪些字符是按什么顺序出现的,如果每次字符都相同,则存储该字符,否则为零在“abcxabcyabczabcyabc”中,字符“b”前面总是有“a”,后面跟着“c”:

找到最大重复子字符串后,将其打印出来:

// print out the maximum length string:
int j = startingChar;
while(j != 0)
{
    cout << (char)j;
    j = next[j];
}
cout << endl;
//打印出最大长度的字符串:
int j=起始字符;
而(j!=0)
{

家庭作业?那不是“为我做”网站。试着写一些代码,如果出了什么问题就回来。好的,但至少展示一下你的代码。我试图通过在两个索引I和j之间生成子字符串来解决这个问题。之后,使用在O(n)中运行的Z算法来查找每种情况下这些子字符串的出现次数。但是总的复杂度是O(n^3)。单个字符是子字符串吗?如果是,那么重复次数最多的子字符串必须重复最常见字符的次数。对吗?@samgak是的,你是对的,但我正在寻找所有子字符串中重复时间最长的子字符串。请参阅本文中的示例。
map<ll,vector<string>> m;
    string s; cin >> s;
    for(ll i=0;i<s.length();i++){
        string c;
        for(ll len=0; i+len<s.length();len++){
            c+=s[i+len];
            ll z[N];
            ll l=0,r=0;
            string kk;
            for(ll p=0;p<c.length();p++){
                kk+=c[p];
            }
            kk+="#";
            for(ll p=0;p<s.length();p++){
                kk+=s[p];
            }
            for(ll k=1;k<kk.length();k++){
                if(k>r){
                    l=r=k;
                    while(r<c.length()&&kk[r-l]==kk[r])r++;
                    z[k]=r-l;
                    r--;
                }
                else{
                    ll m=k-l;
                    if(z[m]<r-k+l)z[k]=z[m];
                    else{
                        l=k;
                        while(r<c.length()&&kk[r-l]==kk[r])r++;
                        z[k]=r-l;
                        r--;
                    }
                }
            }
            ll occ=0;
            for(ll n=0;n<kk.length();n++){
                if(z[n]==c.length())occ++;
            }
            m[occ].push_back(c);
        }
    }
string s; cin >> s;
int i, freq[256];
char prev[256], next[256];
for(i = 1; i < 256; i++)
    freq[i] = prev[i] = next[i] = 0;
int maxFreq = 0;
for(i = 0; i < s.length(); i++)
{
    char c = s[i];
    char p = (i == 0) ? 0 : s[i-1];
    char n = (i < s.length() - 1) ? s[i+1] : 0;
    if(freq[c] == 0) // first time to encounter this character
    {
        prev[c] = p;
        next[c] = n;
    }
    else // check if it is always preceded and followed by the same characters:
    {
        if(prev[c] != p)
            prev[c] = 0;
        if(next[c] != n)
            next[c] = 0;
    }
    // increment frequency and track the maximum:
    if(++freq[c] > maxFreq)
        maxFreq = freq[c];
}

if(maxFreq == 0)
    return 0;
int maxLen = 0;
int startingChar = 0;
for(i = 1; i < 256; i++)
{
    // should have a frequency equal to the max and not be preceded
    // by the same character each time (or it is in the middle of the string)
    if((freq[i] == maxFreq) && (prev[i] == 0))
    {
        int len = 1, j = i;
        while(next[j] != 0)
        {
            len++;
            j = next[j];
        }
        if(len > maxLen)
        {
            maxLen = len;
            startingChar = i;
        }
    }
}
// print out the maximum length string:
int j = startingChar;
while(j != 0)
{
    cout << (char)j;
    j = next[j];
}
cout << endl;