部分文字列の長さは1,2,3 ... です。解決しようとしていた問題は、最大回数発生した部分文字列を見つけることでした。だから、それは基本的に最大頻度を持つキャラクターを見つけることに踏み切った。 しかし、私はO(n)のサフィックスツリーを使って最も長い繰り返し部分文字列を見つけることができることを発見しました。 しかし、接尾辞ツリーは長さを優先順位として保持する部分文字列を返します。 最も頻繁に発生する部分文字列を探したいと思っていました。例えばのために :最大最大繰返し部分文字列
In the following string: ABCZLMNABCZLMNABC
A suffix tree will return ABCZLMN as the longest repeating substring.
However, what I am looking for is ABC; as it is the longest out of all the ones having frequency = 3.
私は2つのインデックスiとjの間の部分文字列を生成することにより、この問題を解決しようとしました。その後、O(n)で実行されているZアルゴリズムを使用して、それぞれの場合にこれらの部分文字列の出現を見つける。しかし、総複雑さはO(N^3)
私はO(n^3)コード
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);
}
}
だった私はそれを効率的に行うための適切な解決策を見つけることができないのです。 助けてください。 ありがとうございます。
Heh ...宿題ですか? SOは "私のためにやる"サイトではありません。いくつかのコードを書こうとして、何かがうまくいかない場合に戻ってください。 – folibis
あなたのコードは少なくとも表示してください。 – folibis
私は2つのインデックスiとjの間に部分文字列を生成することでこの問題を解決しようとしました。その後、O(n)で実行されているZアルゴリズムを使用して、それぞれの場合にこれらの部分文字列の出現を見つける。しかし、全体の複雑さはO(n^3)でした。 –