web-dev-qa-db-ja.com

文字列なしの最長サブシーケンス

サブストリングとしてYを含まないストリングXで最長のサブシーケンスを見つける動的プログラミングアルゴリズムはありますか?この問題は、最長の共通サブシーケンスや文字列など、他のDP文字列アルゴリズムと非常に似ているように見えます。オーバーラップするYの発生を処理できる必要があります。

これは2状態のDP問題である可能性があります。状態[s_pos、t_pos]は、文字列S [pos _ .. M]を部分文字列として持たないs_posで始まる文字列Sの最も長い部分列です。 Nは文字列Sの長さで、Mは文字列Tの長さです。ただし、私の遷移は正しくありません。S= aaabcおよびT = aabcの場合は取得されません。問題はelseステートメントにあります-文字が等しい場合に遷移する方法がわかりません。 実際には、ifブランチが間違っていると感じています...誰かが間違っている可能性を知っていますか?

S = aaabおよびT = aabの場合も失敗します。失敗する理由を説明できます。solve(0、0)を呼び出すと仮定します。 solve(0、0)はsolve(1、1)を呼び出します。 solve(1、1)はsolve(2、2)を呼び出します。 s [2]!= t [2]なので、solve(3、0)から検索を再開します。ただし、aabは部分文字列であり、これをチェックしたり、このケースを考慮したりすることはありません...

int solve(int s_pos, int t_pos)
{
    if (s_pos >= N || t_pos >= M) return 0;
    if (t_pos == M - 1 && s[s_pos] == t[t_pos]) return 0;
    int ret = 0;
    if (s[s_pos] != t[t_pos])
    {
        int tmp = solve(s_pos + 1, 0);
        ret = max(ret, tmp + 1);
    }
    else
    {
        for (int i = s_pos + 1; i < N; i++)
        {
            int tmp = solve(i, t_pos + 1);
            if (tmp != 0)
            {
                ret = max(ret, 1 + tmp);
            }
        }
    }
    return ret;
}
8
user83834

これでうまくいくはずです。私はそれをベーシックに似たメタコードで書いた。

LONGEST = ""
while N>0
  POS = find(T,S)
  if POS>0 then
    SUB = left(S,POS)
  else
    SUB = S
    POS = N
  endif
  if len(SUB) > len(LONGEST) then
    LONGEST = SUB
  endif
  N = N-POS
wend
1
burlip

主な問題は、elseステートメント内のforループであり、関数を再帰的に呼び出すことです。

再帰または反復のいずれかのアプローチを選択しますが、それらを混合することは間違っているようです。

私は反復的なアプローチで行きます。

関数の外に空のリストを作成します。

次にsolveを呼び出します。

この関数でこのアプローチを試してください:

文字列をループします。現在の文字がサブシーケンスの先頭でない場合は、その文字を保持文字列に入れます。これは文字列を構築します。それがサブシーケンスを開始する場合、それらの文字を別の保持ストリングに追加します。サブシーケンスに対して一致する数をマークします。各文字を1つずつ、すでにサブシーケンスと一致している場合は、最初の文字と一致するかどうかを確認し、次に一致する次の位置の文字と一致するかどうかを確認します。それがサブシーケンスと一致する場合、その前のすべて(保持ストリング内)がリストに入れられます。

したがって、基本的には、勝つ可能性のあるシーケンスである可能性があるものを追跡する必要があり、サブシーケンスが別のサブシーケンス内にある可能性があることを追跡する必要があります。

複数の保持文字列が必要な場合がありますが、2つの保持文字列を使用する単純なアプローチを実装し、さまざまな例を調べて、別の保持文字列が必要かどうかがわかるまで各ステップで何が起こっているかを書き留めます。

0
James Black