-1

整列の目的で、「aaa」などの値を持つ行と列を持つマトリックスを作成しようとしています。しかし、実行するとエラーが発生します。以下は私のコードです

public class compute_matrix {
  static String seq1="aaa";
  static String seq2="aaa";
  static int[][] matrix;
  static int max_row;
  static int max_col;
  private static int match_reward=1;
  private static int mismatch_penalty= -1;
  private static int gap_cost= -1;
  private static boolean case_sensitive;

  private static boolean isCaseSensitive() {
    return case_sensitive;
  }

  private static int max(int ins, int sub, int del, int i) {
    if (ins > sub) {
        if (ins > del) {
            return ins > i? ins : i;
        } else {
            return del > i ?del : i;
        }
    } else if (sub > del) {
        return sub> i ? sub : i;
    } else {
        return del > i ? del : i;
    }
}

 protected char sequence[];

   public static void main(String args[]){
    int r, c, rows, cols, ins, sub, del, max_score;

    rows = seq1.length()+1;
    cols = seq2.length()+1;

    matrix = new int [rows][cols];

    // initiate first row
    for (c = 0; c < cols; c++)
        matrix[0][c] = 0;

    // keep track of the maximum score
    max_row = max_col = max_score = 0;

    // calculates the similarity matrix (row-wise)
    for (r = 1; r < rows; r++)
    {
        // initiate first column
        matrix[r][0] = 0;

        for (c = 1; c < cols; c++)
        {
                        sub = matrix[r-1][c-1] + scoreSubstitution(seq1.charAt(r),seq2.charAt(c));
            ins = matrix[r][c-1] + scoreInsertion(seq2.charAt(c));

            del = matrix[r-1][c] + scoreDeletion(seq1.charAt(r));

            // choose the greatest
            matrix[r][c] = max (ins, sub, del, 0);

            if (matrix[r][c] > max_score)
            {
                // keep track of the maximum score
                max_score = matrix[r][c];
                max_row = r; max_col = c;
            }
        }
    }
     }

private static int scoreSubstitution(char a, char b) {
   if (isCaseSensitive())
        if (a == b)
            return match_reward;
        else
            return mismatch_penalty;
    else
        if (Character.toLowerCase(a) == Character.toLowerCase(b))
            return match_reward;
        else
            return mismatch_penalty;
}

private static int scoreInsertion(char a) {
 return gap_cost;
}

private static int scoreDeletion(char a) {
    return gap_cost;
}
public char charAt (int pos)
{
    // convert from one-based to zero-based index
    return sequence[pos-1];
}

  }

私のエラーはこれを表示しています

              Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3
    at java.lang.String.charAt(String.java:695)
    at compute_matrix.main(compute_matrix.java:67)

Javaの結果:1

4

3 に答える 3

4
   rows = seq1.length()+1;
    cols = seq2.length()+1;

    matrix = new int [rows][cols];

そして後で:

   for (c = 1; c < cols; c++)
    {
   //when c == cols-1, it is also `seq2.length()`
   //the access to seq2.charAt(c) will cause this exception then.
                    sub = matrix[r-1][c-1] + scoreSubstitution(seq1.charAt(r),seq2.charAt(c));
        ins = matrix[r][c-1] + scoreInsertion(seq2.charAt(c));

        del = matrix[r-1][c] + scoreDeletion(seq1.charAt(r));

上記のループでc == cols-1は、がの場合、seq2.length()へのアクセスseq2.charAt(c)によってこの例外が発生します。

行と列の数をに初期化し、length() + 1後で0から長さ(両端を含む)まで繰り返しますが、文字列には文字のみが含まれますlength()-0からnまでの排他的です。

過去にCプログラマーであった場合\0、文字列の最後にターミネータが必要だと思います。Javaでは、これらはありません-Stringオブジェクトであるため-正確な長さを示すフィールドを保持できます。文字列の最後の文字を意味するのは、実際にはそこにある最後の文字です。

于 2012-10-18T21:21:29.700 に答える
0

コードの60行 目でsub = matrix[r-1][c-1] + scoreSubstitution(seq1.charAt(r),seq2.charAt(c)); は、rの最大値は4であるため、seq.charAt(3)を検索しても何も表示されないため、インデックスが範囲外であることが示されます。

于 2012-10-18T21:28:25.017 に答える
0

私はあなたのコードをより標準的なJavaにリファクタリングしました。

私が変更したもの:

  • このクラスは現在SimilarityMatrix、より適切な自己文書化名と呼ばれています
  • 変数宣言は、メインの上部ではなく、使用される場所で発生するようになりました
  • 作業は、mainメソッドではなく、クラスのインスタンスで実行されるようになりました。
  • Math.max(int, int)自分でローリングする代わりに、ビルトインを使用しました
  • ネストされた不要なifステートメントをたくさん削除しました。Javaの短絡評価はここで役立ちます
  • randとandcr+1両方がc+1計算ループで頻繁に使用されるため、両方を追跡します
  • 静的状態への依存関係の多くを削除しました(多くのものをインスタンス変数にしました)
  • 残っている静的状態はすべて最終的なものになりました(私はそれらを定数にしました)
  • より多くのjava-y変数名を使用しました(javaの人々はキャメルケースが本当に好きです)

public class SimilarityMatrix
{
    public static final int matchReward = 1;
    public static final int mismatchPenalty = -1;
    public static final int gapCost = -1;

    private int[][] matrix;
    private int maxRow = 0;
    private int maxCol = 0;
    private boolean caseSensitive = false;

    SimilarityMatrix(String s1, String s2, boolean dontIgnoreCase)
    {
        this(s1, s2);
        caseSensitive = dontIgnoreCase;
    }

    SimilarityMatrix(String s1, String s2)
    {
        int rows = s1.length() + 1;
        int cols = s2.length() + 1;
        matrix = new int[rows][cols];

        int max_score = 0;

        for (int x = 0; x < cols; x++)
        {
            matrix[0][x] = 0;
            matrix[x][0] = 0;
        }

        for (int r = 0, rp1 = 1; rp1 < rows; ++r, ++rp1)
        {
            for (int c = 0, cp1 = 1; cp1 < rows; ++c, ++cp1)
            {
                int sub = matrix[r][c] + scoreSubstitution(s1.charAt(r), s2.charAt(c));
                int ins = matrix[rp1][c] + scoreInsertion(s2.charAt(c));

                int del = matrix[r][cp1] + scoreDeletion(s1.charAt(r));

                // choose the greatest
                matrix[rp1][cp1] = Math.max(Math.max(ins, sub), Math.max(del, 0));

                if (matrix[rp1][cp1] > max_score)
                {
                    // keep track of the maximum score
                    max_score = matrix[rp1][cp1];
                    maxRow = rp1;
                    maxCol = cp1;
                }
            }
        }
    }

    public static void main(String args[])
    {
        SimilarityMatrix me = new SimilarityMatrix("aaa", "aaa");
        System.out.println(me.getMaxRow() + " " + me.getMaxCol());
    }

    private int scoreSubstitution(char a, char b)
    {
        if ((a == b && caseSensitive) || Character.toLowerCase(a) != Character.toLowerCase(b))
            return matchReward;
        else
            return mismatchPenalty;
    }

    public int getMaxRow()
    {
        return maxRow;
    }

    public int getMaxCol()
    {
        return maxCol;
    }

    private int scoreInsertion(char a)
    {
        return gapCost;
    }

    private int scoreDeletion(char a)
    {
        return gapCost;
    }
}
于 2012-10-18T21:59:56.153 に答える