これは Nussinov アルゴリズムに似たタスクであり、アラインメントのギャップ、挿入、または不一致を許可しないため、実際にはさらに単純です。
長さ N の文字列 A について、F[-1 .. N, -1 .. N]
テーブルを定義し、次の規則を使用して入力します。
for i = 0 to N
for j = 0 to N
if i != j
{
if A[i] == A[j]
F[i,j] = F [i-1,j-1] + 1;
else
F[i,j] = 0;
}
たとえば、BA O BA B の場合:

これはO(n^2)
時間通りに実行されます。テーブル内の最大値は、最長の自己一致サブシーケンスの終了位置を指します (i - 1 つの発生の終了、j - 別の発生の終了)。最初は、配列はゼロで初期化されていると想定されています。最も長いが、おそらく面白くない自己一致である対角線を除外する条件を追加しました。
さらに考えてみると、この表は対角線上で対称であるため、その半分だけを計算するだけで十分です。また、配列はゼロ初期化されているため、ゼロを割り当てることは冗長です。それが残っている
for i = 0 to N
for j = i + 1 to N
if A[i] == A[j]
F[i,j] = F [i-1,j-1] + 1;
短くなりますが、理解するのが難しくなる可能性があります。計算されたテーブルには、短いものと長いもののすべての一致が含まれます。必要に応じて、さらにフィルタリングを追加できます。
次のステップでは、文字列を回復する必要があります。これは、ゼロ以外のセルから上と左の対角線に続きます。このステップでは、いくつかのハッシュマップを使用して、同じ文字列の自己類似性一致の数をカウントすることも簡単です。通常の文字列と通常の最小長では、少数のテーブル セルのみがこのマップで処理されます。
ハッシュマップを直接使用するには、実際には O(n^3) が必要だと思います。これは、アクセスの最後のキー文字列を何らかの方法で比較する必要があるためです。この比較はおそらく O(n) です。