I am trying to build a matrix with row and column having values such as "aaa" for aligning purposes. but when I run it I get an error. below is my code
我正在尝试构建一个矩阵,其行和列具有诸如“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];
}
}
and my error is displaying this
我的错误是显示这个
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 Result: 1
Java结果:1
3 个解决方案
#1
4
rows = seq1.length()+1;
cols = seq2.length()+1;
matrix = new int [rows][cols];
and then later:
然后:
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));
In the above loop, when c == cols-1
, it is also seq2.length()
, the access to seq2.charAt(c)
will cause this exception then.
在上面的循环中,当c == cols-1时,它也是seq2.length(),对seq2.charAt(c)的访问将导致此异常。
You initialize the number of rows and cols to length() + 1
, while you later iterate from 0 to length (inclusive), while the string contain only length()
chars - from 0 to n exclusive.
您将行数和列数初始化为length()+ 1,而稍后从0迭代到length(包括),而字符串仅包含length()字符 - 从0到n不包括。
If you are a C programmer in your past - I assume you are expecting a \0
terminator at the end of the string. In java you don't have those - since String
is an object - you can hold a field to indicate its exact length. Meaning the last char in the string, is actually the last character there.
如果您是过去的C程序员 - 我假设您期望在字符串末尾有一个\ 0终止符。在java中你没有那些 - 因为String是一个对象 - 你可以保存一个字段来指示它的确切长度。意思是字符串中的最后一个字符,实际上是那里的最后一个字符。
#2
0
in line 60 of your code sub = matrix[r-1][c-1] + scoreSubstitution(seq1.charAt(r),seq2.charAt(c));
max value for r is 4 so when you look up for seq.charAt(3) there is nothingso it shows index out of bound
在你的代码的第60行sub = matrix [r-1] [c-1] + scoreSubstitution(seq1.charAt(r),seq2.charAt(c)); r的最大值是4,所以当你查找seq.charAt(3)时,没有任何东西显示索引超出范围
#3
0
I refactored your code into more canonical java.
我将你的代码重构为更规范的java。
The things I've changed:
我改变的事情:
- The class is now called
SimilarityMatrix
, a more appropriate, self documenting name - variable declarations now happen where they get used as opposed to at the top of main
- The work is now done in an instance of the class rather than the main method
- I used the built in
Math.max(int, int)
instead of rolling my own - I removed a lot of unnecessary nested if statements. Java's short circuit evaluation helps here
- Since both
r
andc
as well asr+1
andc+1
are used frequently in your calculation loop, I track both - I removed many of the dependencies on static state (made many things instance variables)
- Static state that remains is all final now (I made them constants)
- Used more java-y variable names (java people really like their camel case)
该类现在称为SimilarityMatrix,一个更合适的自我记录名称
变量声明现在发生在使用它们而不是在main的顶部
现在,该工作是在类的实例中完成的,而不是主方法
我使用内置的Math.max(int,int)而不是自己滚动
我删除了很多不必要的嵌套if语句。 Java的短路评估有助于此
由于r和c以及r + 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;
}
}
#1
4
rows = seq1.length()+1;
cols = seq2.length()+1;
matrix = new int [rows][cols];
and then later:
然后:
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));
In the above loop, when c == cols-1
, it is also seq2.length()
, the access to seq2.charAt(c)
will cause this exception then.
在上面的循环中,当c == cols-1时,它也是seq2.length(),对seq2.charAt(c)的访问将导致此异常。
You initialize the number of rows and cols to length() + 1
, while you later iterate from 0 to length (inclusive), while the string contain only length()
chars - from 0 to n exclusive.
您将行数和列数初始化为length()+ 1,而稍后从0迭代到length(包括),而字符串仅包含length()字符 - 从0到n不包括。
If you are a C programmer in your past - I assume you are expecting a \0
terminator at the end of the string. In java you don't have those - since String
is an object - you can hold a field to indicate its exact length. Meaning the last char in the string, is actually the last character there.
如果您是过去的C程序员 - 我假设您期望在字符串末尾有一个\ 0终止符。在java中你没有那些 - 因为String是一个对象 - 你可以保存一个字段来指示它的确切长度。意思是字符串中的最后一个字符,实际上是那里的最后一个字符。
#2
0
in line 60 of your code sub = matrix[r-1][c-1] + scoreSubstitution(seq1.charAt(r),seq2.charAt(c));
max value for r is 4 so when you look up for seq.charAt(3) there is nothingso it shows index out of bound
在你的代码的第60行sub = matrix [r-1] [c-1] + scoreSubstitution(seq1.charAt(r),seq2.charAt(c)); r的最大值是4,所以当你查找seq.charAt(3)时,没有任何东西显示索引超出范围
#3
0
I refactored your code into more canonical java.
我将你的代码重构为更规范的java。
The things I've changed:
我改变的事情:
- The class is now called
SimilarityMatrix
, a more appropriate, self documenting name - variable declarations now happen where they get used as opposed to at the top of main
- The work is now done in an instance of the class rather than the main method
- I used the built in
Math.max(int, int)
instead of rolling my own - I removed a lot of unnecessary nested if statements. Java's short circuit evaluation helps here
- Since both
r
andc
as well asr+1
andc+1
are used frequently in your calculation loop, I track both - I removed many of the dependencies on static state (made many things instance variables)
- Static state that remains is all final now (I made them constants)
- Used more java-y variable names (java people really like their camel case)
该类现在称为SimilarityMatrix,一个更合适的自我记录名称
变量声明现在发生在使用它们而不是在main的顶部
现在,该工作是在类的实例中完成的,而不是主方法
我使用内置的Math.max(int,int)而不是自己滚动
我删除了很多不必要的嵌套if语句。 Java的短路评估有助于此
由于r和c以及r + 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;
}
}