技能一覧 › 大学数学 アルゴリズムと計算量

最長共通部分列

の表を一致すれば 、そうでなければ で埋めて、2 つの文字列の最長共通部分列の長さを求められる

前提

説明

2 つの文字列に共通して含まれる「部分列」のうち、最も長いものの長さを、2 次元の表を埋める動的計画法で求めます。部分列とは、文字列からいくつかの文字を取り除き、残りを元の順番のまま並べたものです(とびとびでもよい)。たとえば から や が取り出せます。2 つの DNA 配列の似ている度合いや、2 つのファイルの差分(diff)を調べる場面の基礎になる計算です。

なぜそうしてよいのか

硬貨の問題では「 円の答え」を「より小さい金額の答え」から作りました。ここでも同じ考え方を使います。文字列 、 について、先頭 文字 と先頭 文字 の最長共通部分列の長さを とおきます。どちらかが空( または )なら共通部分列は空だけなので です。求めたいのは です。今度は添字が 2 つあるので、表は 2 次元になります。

のとき: と の最長共通部分列の後ろにこの文字を付ければよいので、 です。逆に、 の共通部分列 を 1 つとります。 の最後の文字が にも にも対応していないなら、 は の共通部分列なので、長さは 以下です。最後の文字が だけに対応しているなら、その文字は と等しいので、 側の対応先を に付け替えても共通部分列のままです( だけに対応している場合も同様です)。こうして最後の文字が と の両方に対応している形にでき、それを取り除いた残りは の共通部分列になります。どの場合も長さは 以下なので、 が成り立ちます。

のとき:共通部分列の同じ 1 文字が と の両方に対応することはありえません(もし対応すれば になってしまいます)。したがって、 を使わない( の共通部分列)か、 を使わない( の共通部分列)かのどちらかです。よって となります。どちらの式も「左上・上・左」のマスしか使わないので、表を上の行から順に、各行を左から右へ埋めれば、必要な値は常にそろっています。表は マスあり、1 マスの計算は定数時間なので、全体の計算量は です。

手順

  1. 文字列を 、 とし、 の表 ()を用意する。

  2. 0 行目と 0 列目をすべて 0 にする:。

  3. の順に行を選び、各行の中を の順に進みながら、 と を比べる。

  4. 一致すれば (左上 )、一致しなければ (上と左の大きいほう)とする。

  5. 右下の値 が、最長共通部分列の長さである。

例題

文字列 と の最長共通部分列の長さを求めよ。

例題の解答

【手順1】 なので、 の表を用意する。、 である。
【手順2】 とする。
【手順3・4】1 行ずつ埋める(各行は の値を並べたもの)。
・(A): はどれも A と一致しない。上も左も 0 なので、行は 。
・(B): は B と B が一致するので 。(D)は 、(C)は 。 は B と B が一致するので 。行は 。
・(C): は 。 は 。 は C と C が一致するので 。 は 。行は 。
・(B): は一致するので 。 は 。 は 。 は一致するので 。行は 。
・(D): は 。 は D と D が一致するので 。 は 。 は 。行は 。
【手順5】 である。実際、 は の 2・3・4 文字目、 の 1・3・4 文字目として取り出せる共通部分列で、長さは 3 である。

答え:

よくある誤り

この説明は AI が書き、別の AI が例題を独立に解いて答えを確かめ、説明を一歩ずつ査読しました。

入口の問題

この技能を使う問題