O(n) アルゴリズムが存在するかどうかはわかりません。これは O(n*n) の動的ソリューションです。役に立つかもしれません。lcs_con[i][j] が、配列 A の要素 A_i と配列 B の要素 B_j で終わる最長の共通連続サブシーケンスを表すとします。次に、以下の式を取得できます。
lcs_con[i][j]=0 if i==0 or j==0
lcs_con[i][j]=0 if A_i != B_j
lcs_con[i][j]=lcs_con[i-1][j-1] if A_i==B_j
計算中に lcs_con[i][j] の最大値と終了インデックスを記録して、最長の共通連続サブシーケンスを取得できます。コードは以下のとおりです。
#include<iostream>
using namespace std;
int main()
{
char A[7]={'a','b','a','b','b','b','a'};
char B[7]={'a','d','b','b','b','c','n'};
int lcs_con[8][8];
memset(lcs_con,0,8*8*sizeof(int));
int result=-1;
int x=-1;
int y=-1;
for(int i=1;i<=7;++i)
for(int j=1;j<=7;++j)
{
if(A[i-1]==B[j-1])lcs_con[i][j]=lcs_con[i-1][j-1]+1;
else lcs_con[i][j]=0;
if(lcs_con[i][j]>result)
{
result=lcs_con[i][j];
x=i;
y=j;
}
}
if(result==-1)cout<<"There are no common contiguous subsequence";
else
{
cout<<"The longest common contiguous subsequence is:"<<endl;
for(int i=x-result;i<x;i++)cout<<A[i];
cout<<endl;
}
getchar();
getchar();
return 0;
}
それが役に立てば幸い!