泛型矩阵类进行加、乘运算

题目描述:对于所有的矩阵,除了元素类型不同以外,他们的加法和乘法操作都是类似的。因此,可以设计一个父类,不管他们的元素类型是什么,该父类描述所有类型的矩阵共享的通用的操作,还可以创建若干个适用于指定矩阵类型的子类。本文给出了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方法就可以使用它们。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会为您解答这个问题。 以下是实现泛型矩阵的基本运算的代码: ``` #include<iostream> #include<cstdlib> #include<ctime> using namespace std; template<typename T> class Matrix { private: int m, n; T **data; public: Matrix(int m=0, int n=0):m(m), n(n) { data = new T*[m]; for(int i=0; i<m; i++) { data[i] = new T[n]; for(int j=0; j<n; j++) { data[i][j] = 0; } } } Matrix(const Matrix &matrix):m(matrix.m), n(matrix.n) { data = new T*[m]; for(int i=0; i<m; i++) { data[i] = new T[n]; for(int j=0; j<n; j++) { data[i][j] = matrix.data[i][j]; } } } Matrix operator+(const Matrix &matrix) { Matrix result(m, n); for(int i=0; i<m; i++) { for(int j=0; j<n; j++) { result.data[i][j] = data[i][j] + matrix.data[i][j]; } } return result; } Matrix operator-(const Matrix &matrix) { Matrix result(m, n); for(int i=0; i<m; i++) { for(int j=0; j<n; j++) { result.data[i][j] = data[i][j] - matrix.data[i][j]; } } return result; } void show() { for(int i=0; i<m; i++) { for(int j=0; j<n; j++) { cout << data[i][j] << " "; } cout << endl; } } ~Matrix() { for(int i=0; i<m; i++) { delete[] data[i]; } delete[] data; } }; class SquareMatrix: public Matrix<int> { public: SquareMatrix(int n=0):Matrix<int>(n, n) {} SquareMatrix(const SquareMatrix &matrix):Matrix<int>(matrix) {} int determinant() { if(m != n) { cout << "该矩阵不是方阵,无法求行列式" << endl; return 0; } int det = 0; if(n == 1) { det = data[0][0]; } else { for(int i=0; i<n; i++) { SquareMatrix submatrix(n-1); for(int j=1; j<n; j++) { for(int k=0; k<n; k++) { if(k != i) { submatrix.data[j-1][k<k?k:(k-1)] = data[j][k]; } } } det += (i%2==0?1:-1) * data[0][i] * submatrix.determinant(); } } return det; } void leftMultiply(const Matrix<int> &matrix) { if(n != matrix.m) { cout << "矩阵尺寸不匹配,无法左乘" << endl; return; } Matrix<int> result(m, matrix.n); for(int i=0; i<m; i++) { for(int j=0; j<matrix.n; j++) { for(int k=0; k<n; k++) { result.data[i][j] += data[i][k] * matrix.data[k][j]; } } } result.show(); } }; int main() { srand(time(NULL)); Matrix<int> A(5, 6), B(5, 6), C(5, 6); for(int i=0; i<5; i++) { for(int j=0; j<6; j++) { A[i][j] = rand() % 10; B[i][j] = rand() % 10; C[i][j] = rand() % 10; } } cout << "矩阵A:" << endl; A.show(); cout << "矩阵B:" << endl; B.show(); cout << "矩阵C:" << endl; C.show(); cout << "A + B:" << endl; (A+B).show(); cout << "A - C:" << endl; (A-C).show(); SquareMatrix D(4), E(4); for(int i=0; i<4; i++) { for(int j=0; j<4; j++) { D[i][j] = rand() % 10; E[i][j] = rand() % 10; } } cout << "方阵D:" << endl; D.show(); cout << "方阵E:" << endl; E.show(); cout << "D * E:" << endl; (D*E).show(); cout << "D 的行列式:" << endl; cout << D.determinant() << endl; cout << "E 的行列式:" << endl; cout << E.determinant() << endl; cout << "D * A:" << endl; D.leftMultiply(A); return 0; } ``` 以上代码实现了泛型矩阵的基本运算,包括矩阵减法、按照 m 行 n 列打印出矩阵的 show 方法、析构函数的内存释放;并定义了一个4*4方阵作为矩阵的派生,包含成员方法求行列式的值、成员方法左乘矩阵打印出结果,并进行了相应的规格检查。 在主函数中,随机生成5*6矩阵 A ,5*6矩阵 B ,5*6矩阵 C ,计算 a + b , a - c ;随机生成4*4方阵 D ,4*4方阵 E ,计算 D * E ,计算 D 和 E 的行列式,判断 D * A 的可计算性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值