题目描述:对于所有的矩阵,除了元素类型不同以外,他们的加法和乘法操作都是类似的。因此,可以设计一个父类,不管他们的元素类型是什么,该父类描述所有类型的矩阵共享的通用的操作,还可以创建若干个适用于指定矩阵类型的子类。本文给出了Int和有理数类Rational的实现。
时间:2019.3.30
代码:
public abstract class GenericMatrix <E extends Number>{
protected abstract E add(E o1,E o2);
protected abstract E multiply(E o1,E o2);
protected abstract E zero();
public E[][] addMatrix(E[][]matrix1,E[][]matrix2){
if((matrix1.length!=matrix2.length)||(matrix1[0].length!=matrix2[0].length)){
throw new RuntimeException("The matrices do not have the same size");
}
E[][] result=(E[][])new Number[matrix1.length][matrix1[0].length];
for(int i=0;i<result.length;i++)
for(int j=0;j<result[i].length;j++){
result[i][j]=add(matrix1[i][j],matrix2[i][j]);
}
return result;
}
public E[][] mulyiplyMartix(E[][]matrix1,E[][]matrix2){
if((matrix1.length!=matrix2.length)||(matrix1[0].length!=matrix2[0].length)){
throw new RuntimeException("The matrices do not have the same size");
}
E[][] result=(E[][])new Number[matrix1.length][matrix2[0].length];
for(int i=0;i<result.length;i++)
for(int j=0;j<result[0].length;j++){
result[i][j]=zero();
for(int k=0;k<matrix1[0].length;k++){
result[i][j]=add(result[i][j],multiply(matrix1[i][k],matrix2[k][j]));
}
}
return result;
}
public static void printResult(Number[][] m1,Number[][] m2,Number[][]m3,char op){
for(int i=0;i<m1.length;i++){
for(int j=0;j<m1[0].length;j++)
System.out.print(" "+m1[i][j]);
if(i==m1.length/2)
System.out.print(" "+op+" ");
else
System.out.print(" ");
for(int j=0;j<m2.length;j++)
System.out.print(" "+m2[i][j]);
if(i==m1.length/2)
System.out.print(" = ");
else
System.out.print(" ");
for(int j=0;j<m3.length;j++)
System.out.print(m3[i][j]+" ");
System.out.println();
}
}
}
public class IntegerMatrix extends GenericMatrix<Integer>{
@Override
protected Integer add(Integer o1, Integer o2) {
return o1+o2;
}
@Override
protected Integer multiply(Integer o1, Integer o2) {
return o1*o2;
}
@Override
protected Integer zero() {
return 0;
}
}
public class RationalMatrix extends GenericMatrix<Rational>{
@Override
protected Rational add(Rational o1, Rational o2) {
return o1.add(o2);
}
@Override
protected Rational multiply(Rational o1, Rational o2) {
return o1.multiply(o2);
}
@Override
protected Rational zero() {
return new Rational(0,1);
}
}
public class Rational extends Number{
private long numerator=0;
private long denominator=1;
public Rational(){
this(0,1);
}
public Rational(long num1,long num2){
long gcd=gcd(num1,num2);
this.numerator=(num2>0?1:-1)*num1/gcd;
this.denominator=Math.abs(num2)/gcd;
}
private static long gcd(long n,long d){
long n1=Math.abs(n);
long n2=Math.abs(d);
int gcd=1;
for(int k=1;k<=n1&&k<=n2;k++){
if(n1%k==0&&n2%k==0)
gcd=k;
}
return gcd;
}
public String toString(){
if(denominator==1)
return numerator+"";
else
return numerator+"/"+denominator;
}
@Override
public double doubleValue() {
// TODO 自动生成的方法存根
return numerator*1.0/denominator;
}
@Override
public float floatValue() {
// TODO 自动生成的方法存根
return (float) doubleValue();
}
@Override
public int intValue() {
// TODO 自动生成的方法存根
return (int) doubleValue();
}
@Override
public long longValue() {
// TODO 自动生成的方法存根
return (long) doubleValue();
}
public long getNumerator(){
return numerator;
}
public long GetDenominator(){
return denominator;
}
public Rational add(Rational second){
long n=numerator*second.GetDenominator()+denominator*second.getNumerator();
long d=denominator*second.GetDenominator();
return new Rational(n,d);
}
public Rational multiply(Rational second){
long n=numerator*second.getNumerator();
long d=denominator*second.GetDenominator();
return new Rational(n,d);
}
}
public class TestIntegerMatrix {
public static void main(String args[]){
Integer[][] m1=new Integer[][]{{1,2,3},{4,5,6},{1,1,1}};
Integer[][] m2=new Integer[][]{{1,1,1},{2,2,2},{0,0,0}};
IntegerMatrix integerMatrix=new IntegerMatrix();
System.out.println("\nm1+m2 is");
GenericMatrix.printResult(m1, m2, integerMatrix.addMatrix(m1, m2), '+');
System.out.println("\nm1*m2 is");
GenericMatrix.printResult(m1, m2, integerMatrix.mulyiplyMartix(m1, m2), '+');
}
}
public class TestRationalMatrix {
public static void main(String []args){
Rational[][] m1=new Rational[3][3];
Rational[][] m2=new Rational[3][3];
for(int i=0;i<m1.length;i++)
for(int j=0;j<m1[0].length;j++){
m1[i][j]=new Rational(i+1,j+5);
m2[i][j]=new Rational(i+1,j+6);
}
RationalMatrix rationalMartrix=new RationalMatrix();
System.out.println("\nm1+m2 is");
GenericMatrix.printResult(m1, m2, rationalMartrix.addMatrix(m1, m2), '+');
System.out.println("\nm1*m2 is");
GenericMatrix.printResult(m1, m2, rationalMartrix.mulyiplyMartix(m1, m2), '*');
}
}
IntegerMatrix和RationalMatrix是GenericMatrix的具体子类。这两个类实现了在GenericMatrix类中定义的add、multiply和zero方法。矩阵元素的类型Number的泛型子类。这样就可以使用任意Number子类的对象,只要在子类中实现了add、multiply和zero方法就可以使用它们。