8

整列したい100文字の配列が2つあります(最大、同じサイズでない場合もあります)。他と違うキャラクターがいる場合は「-」を付けたい。動的計画法に基づくNeedleman-Wunschアルゴリズムと、同じく動的計画法に基づく一般的なローカルアラインメント手法であるSmith-Watermanアルゴリズムを見つけましたが、これらは私がやりたいことには複雑すぎるようです。Javaで必要なのはおそらく50行未満の単純なアルゴリズムだけです。このコードは後でアセンブリ言語に変換されるので、単純なアルゴリズムが必要なのはなぜですか。

この種のアラインメントをdiffアルゴリズムで行う方法はありますか?はいの場合、誰かが私にこれを行う方法を教えてもらえますか?biostarセクションを検索しましたが、前述の2つのアルゴリズムを使用する必要があるようです。

英語は私の母国語ではないので、間違ったキーワードを検索した可能性があります。

私のプログラムはすでにNeedlemanアルゴリズムとその約200行のコードで動作します。

必要な入力/出力の例:

Input
Array 1 : MKNLASREVNIYVNGKLV
Array 2 : QMASREVNIYVNGKL


Output
Array 1 (or a simple print) : -MKNLASREVNIYVNGKLV 
Array 2 (or a simple print) : QM---ASREVNIYVNGKL-
4

2 に答える 2

11

まさにあなたが望むことをするレーベンシュタイン距離のバリエーションを使用する:

出力

-MKNLASREVNIYVNGKLV
QM---ASREVNIYVNGKL-

コード:

public class Main {
    public static void main(String[] args) {
        String[] aligned = align("MKNLASREVNIYVNGKLV", "QMASREVNIYVNGKL");
        System.out.println(aligned[0]);
        System.out.println(aligned[1]);
    }

    public static String[] align(String a, String b) {
        int[][] T = new int[a.length() + 1][b.length() + 1];

        for (int i = 0; i <= a.length(); i++)
            T[i][0] = i;

        for (int i = 0; i <= b.length(); i++)
            T[0][i] = i;

        for (int i = 1; i <= a.length(); i++) {
            for (int j = 1; j <= b.length(); j++) {
                if (a.charAt(i - 1) == b.charAt(j - 1))
                    T[i][j] = T[i - 1][j - 1];
                else
                    T[i][j] = Math.min(T[i - 1][j], T[i][j - 1]) + 1;
            }
        }

        StringBuilder aa = new StringBuilder(), bb = new StringBuilder();

        for (int i = a.length(), j = b.length(); i > 0 || j > 0; ) {
            if (i > 0 && T[i][j] == T[i - 1][j] + 1) {
                aa.append(a.charAt(--i));
                bb.append("-");
            } else if (j > 0 && T[i][j] == T[i][j - 1] + 1) {
                bb.append(b.charAt(--j));
                aa.append("-");
            } else if (i > 0 && j > 0 && T[i][j] == T[i - 1][j - 1]) {
                aa.append(a.charAt(--i));
                bb.append(b.charAt(--j));
            }
        }

        return new String[]{aa.reverse().toString(), bb.reverse().toString()};
    }
}
于 2013-02-23T17:36:36.447 に答える
1

あなたの問題の説明はすぐに私にレーベンシュタイン距離とそれに関連するアルゴリズムを思い起こさせます。それは単純ですが(間違いなく50行未満)、動的計画法にも基づいています。

元のアルゴリズムは必要な変更の数を計算するだけですが、必要な挿入、削除、および置換を見つけるために簡単に変更できます。実際、置換を処理したいかどうかはわかりませんが、たとえばABCとADCをどのように調整しますか?

于 2013-02-23T17:14:17.877 に答える