importjava.util.Scanner;classData{intleft, diagonal, up;
Data(){}
Data(int a, int b, intc){
left=a;
diagonal=b;
up=c;
}publicString toString(){return String.format("(%2d, %2d, %2d)",left, diagonal, up);
}
}public classBlast {//反转字符串
public staticString reverse(String s) {
String str= "";char[] a =s.toCharArray();for (int i = a.length - 1; i >= 0; i--) {
str+=a[i];
}returnstr;
}public staticString pairaln(String s1, String s2) {//得分情况
int MATCH = 2; //匹配
int MISMATCH = -1; //匹配失败
int GAP = -1; //存在gap//初始化
int length1 = s1.length() + 1;int length2 = s2.length() + 1;int[][] score = new int[length2][length1];int[][] pointer = new int[length2][length1];
Data[][] data= newData[length2][length1];
score[0][0] = 0;
pointer[0][0] = 0; //记录选择了那个数据,按照left,diagonal,up顺序
data[0][0] = new Data(0, 0, 0);for (int j = 1; j < length1; j++) {
score[0][j] = GAP *j;
pointer[0][j] = 1;
data[0][j] = new Data(GAP * j, GAP * j, GAP *j);
}for (int i = 1; i < length2; i++) {
score[i][0] = GAP *i;
pointer[i][0] = 3;
data[i][0] = new Data(GAP * i, GAP * i, GAP *i);
}//dp
for (int i = 1; i < length2; i++) {int letter2 = s2.charAt(i - 1);for (int j = 1; j < length1; j++) {intdiagonal_score, left_score, up_score;int letter1 = s1.charAt(j - 1);
diagonal_score= letter1 == letter2 ?score[i- 1][j - 1] + MATCH : score[i - 1][j - 1] +MISMATCH;
up_score= score[i - 1][j] +GAP;
left_score= score[i][j - 1] +GAP;
data[i][j]= newData(left_score, diagonal_score, up_score);if (diagonal_score >=Math.max(up_score, left_score)) {
score[i][j]=diagonal_score;
pointer[i][j]= 2;
}else{if (up_score >=left_score) {
score[i][j]=up_score;
pointer[i][j]= 3;
}else{
score[i][j]=left_score;
pointer[i][j]= 1;
}
}
}
}//得分矩阵
for (int k = 0; k < length2; k++) {for (int l = 0; l < length1; l++) {
System.out.print(data[k][l]+ " ");
}
System.out.println();
}//回溯
int j = length1 - 1;int i = length2 - 1;
String align1= "";
String align2= "";while (true) {if (pointer[i][j] == 0) break;if (pointer[i][j] == 2) {
align1+= s1.charAt(j - 1);
align2+= s2.charAt(i - 1);
i--;
j--;
}if (pointer[i][j] == 1) {
align1+= s1.charAt(j - 1);
align2+= "-";
j--;
}if (pointer[i][j] == 3) {
align1+= "-";
align2+= s2.charAt(i - 1);
i--;
}
}//翻转
align1 =reverse(align1);
align2=reverse(align2);return "序列:\n" + s1 + "\n" + s2 + "\n" + "比对结果:\n" + align1 + "\n" + align2 + "\n";
}public static voidmain(String[] args) {
Scanner in= newScanner(System.in);
System.out.println("请输入第一条序列:");
String seq1=in.next();
System.out.println("请输入第二条序列:");
String seq2=in.next();
System.out.println(pairaln(seq1, seq2));
}
}