(20200429)【C++】矩阵加法+矩阵减法+矩阵乘法+矩阵求逆

参考:

【1】

【2】矩阵作为二维数组处理;

【3】new申请一个二维数组空间:https://blog.csdn.net/sinat_32602421/article/details/105840182

说明:

 1】int *p1 = new int[10];  //返回的是一个指向int的指针int*  

2】int (*p8)[10] = new int[2][10];
new了一个二维数组, 去掉最左边那一维[2], 剩下int[10], 所以返回的是一个指向int[10]这种一维数组的指针int (*)[10].  

3】

C++中用new动态创建二维数组的格式一般是这样: TYPE (*p)[N] = new TYPE [][N]; 其中,TYPE是某种类型,N是二维数组的列数。采用这种格式,列数必须指出,而行数无需指定。在这里,p的类型是TYPE*[N],即是指向一个有N列元素数组的指针。

4】 还有一种方法,可以不指定数组的列数:
     int**p10;   
    p10 = new int*[2];  //二级指针p10,指向int*[2](表示一个有2个元素的指针数组)
    for (int i = 0; i != 2; ++i)
    {
        p10[i] = new int[10];

5】
int (*p3)[2][10] = new int[5][2][10];  new了一个三维数组, 去掉最左边那一维[5], 还有int[2][10], 所以返回的是一个指向二维数组int[2][10]这种类型的指针int (*)[2][10].

————————————————————————————

 

矩阵加法:


//矩阵相加 矩阵相减
#include  <iostream>
#include  <fstream>
#include <iomanip>
using namespace std;

class  trAdd
{
private:
	int m, n, k;
	double  **a, **b, **c;  //a[m][n]+b[m][n]=c[m][n]
public:
	trAdd(int mm, int nn)   //有参数的构造函数
	{
		int i;
		m = mm; 
		n = nn; 
		//动态分配内存空间
		a = new double*[m];      //a[m][n]
		for (i = 0; i < m; i++)
		{
			a[i] = new double[n]; //a[m][n]
		}

		b = new double*[m];  //b[m][n]
		for (i = 0; i < m; i++)
		{
			b[i] = new double[n];//b[m][n]
		}

		c = new double*[m];//c[m][n]
		for (i = 0; i < m; i++)
		{
			c[i] = new double[n];//c[m][n]
		}

	}
	void input();    //从文件读入:a[m][n]与b[m][n]
	void add();      //执行:a[m][n]*b[m][n]=c[m][n]
	void output();   //输出c[m][n]到文件

	~trAdd()   //析构函数 delete空间
	{
		int i;
		for (i = 0; i<m; i++) 
		{ 
			delete[] a[i]; 
		}
		delete[] a;

		for (i = 0; i<n; i++) 
		{ 
			delete[] b[i]; 
		}
		delete[] b;

		for (i = 0; i<m; i++) 
		{ 
			delete[] c[i]; 
		}
		delete[] c;
	}
};

void trAdd::input()      //从文件读入矩阵A与B
{
	int  i, j;
	char str1[20];
	ifstream  fin;
	fin.open("tradd.dat", ios::in);
	//ifstream fin("trAdd.dat");
	strcpy(str1, "tradd.dat");
	if (!fin)
	{
		cout << "\n不能打开这个文件 " << str1 << endl; 
		exit(1);
	}
	for (i = 0; i < m; i++)                       //读入矩阵A
	{
		for (j = 0; j < n; j++)
		{
			fin >> a[i][j];
		}
	}

	for (i = 0; i < m; i++)                       //读入矩阵B
	{
		for (j = 0; j < n; j++)
		{
			fin >> b[i][j];
		}
	}


	fin.close();
}

void trAdd::add()         //执行a[m][n]+b[m][n]=c[m][n]
{
	int i, j, t;
	for (i = 0; i < m; i++)
	{
		for (j = 0; j < n; j++)
		{
			c[i][j] = a[i][j] + b[i][j];
		}
	}


}

void trAdd::output()       //矩阵C写到文件
{
	int  i, j;
	char str2[20];
	ofstream fout;
	fout.open("out.txt", ios::out);
	strcpy(str2, "out.txt");
	if (!fout)
	{
		cout << "\n不能打开这个文件 " << str2 << endl; 
		exit(1);
	}

	for (i = 0; i < m; i++)
	{
		for (j = 0; j < n; j++)
		{
			//fout << "    " << c[i][j];
			//cout << "    " << c[i][j];
			fout << setw(10) << setprecision(5) << c[i][j];
			cout << setw(10) << setprecision(4) << c[i][j];
		}
		fout << endl; cout << endl;
	}
	fout.close();
}

void main()      //主函数
{
	trAdd  c(4, 5);
	c.input();     //从文件读入矩阵A和B
	c.add();       //执行C=AB
	c.output();    //输出矩阵C到文件
}

说明:

从文件读取矩阵元素:

输出结果c[4][5]到文件:

 

矩阵减法:


//矩阵相加 矩阵相减
#include  <iostream>
#include  <fstream>
#include <iomanip>
using namespace std;

class  trMinus
{
private:
	int m, n, k;
	double  **a, **b, **c;  //a[m][n]+b[m][n]=c[m][n]
public:
	trMinus(int mm, int nn)   //有参数的构造函数
	{
		int i;
		m = mm; 
		n = nn; 
		//动态分配内存空间
		a = new double*[m];      //a[m][n]
		for (i = 0; i < m; i++)
		{
			a[i] = new double[n]; //a[m][n]
		}

		b = new double*[m];  //b[m][n]
		for (i = 0; i < m; i++)
		{
			b[i] = new double[n];//b[m][n]
		}

		c = new double*[m];//c[m][n]
		for (i = 0; i < m; i++)
		{
			c[i] = new double[n];//c[m][n]
		}

	}
	void input();    //从文件读入:a[m][n]与b[m][n]
	void add();      //执行:a[m][n]*b[m][n]=c[m][n]
	void output();   //输出c[m][n]到文件

	~trMinus()   //析构函数 delete空间
	{
		int i;
		for (i = 0; i<m; i++) 
		{ 
			delete[] a[i]; 
		}
		delete[] a;

		for (i = 0; i<n; i++) 
		{ 
			delete[] b[i]; 
		}
		delete[] b;

		for (i = 0; i<m; i++) 
		{ 
			delete[] c[i]; 
		}
		delete[] c;
	}
};

void trMinus::input()      //从文件读入矩阵A与B
{
	int  i, j;
	char str1[20];
	ifstream  fin;
	fin.open("trMinus.dat", ios::in);
	//ifstream fin("trMinus.dat");
	strcpy(str1, "trMinus.dat");
	if (!fin)
	{
		cout << "\n不能打开这个文件 " << str1 << endl; 
		exit(1);
	}
	for (i = 0; i < m; i++)                       //读入矩阵A
	{
		for (j = 0; j < n; j++)
		{
			fin >> a[i][j];
		}
	}

	for (i = 0; i < m; i++)                       //读入矩阵B
	{
		for (j = 0; j < n; j++)
		{
			fin >> b[i][j];
		}
	}


	fin.close();
}

void trMinus::add()         //执行a[m][n]+b[m][n]=c[m][n]
{
	int i, j, t;
	for (i = 0; i < m; i++)
	{
		for (j = 0; j < n; j++)
		{
			c[i][j] = a[i][j] - b[i][j];
		}
	}


}

void trMinus::output()       //矩阵C写到文件
{
	int  i, j;
	char str2[20];
	ofstream fout;
	fout.open("out.txt", ios::out);
	strcpy(str2, "out.txt");
	if (!fout)
	{
		cout << "\n不能打开这个文件 " << str2 << endl; 
		exit(1);
	}

	for (i = 0; i < m; i++)
	{
		for (j = 0; j < n; j++)
		{
			//fout << "    " << c[i][j];
			//cout << "    " << c[i][j];
			fout << setw(10) << setprecision(5) << c[i][j];
			cout << setw(10) << setprecision(4) << c[i][j];
		}
		fout << endl; cout << endl;
	}
	fout.close();
}

int main()      //主函数
{
	trMinus  c(4, 5);
	c.input();     //从文件读入矩阵A和B
	c.add();       //执行C=AB
	c.output();    //输出矩阵C到文件
	return 0;
}

输出结果:

 

其实可以将矩阵加法和矩阵减法函数成员放在一个类里面。

 

矩阵乘法:

代码:


//矩阵相乘
#include  <iostream>
#include  <fstream>
#include <iomanip>
using namespace std;

class  trmul
{
private:
	int m, n, k;
	double  **a, **b, **c;  //a[m][n]*b[n][k]=c[m][k]
public:
	trmul(int mm, int nn, int kk)   //有参数的构造函数
	{
		int i;
		m = mm; 
		n = nn; 
		//动态分配内存空间
		k = kk;
		a = new double*[m];      //a[m][n]
		for (i = 0; i < m; i++)
		{
			a[i] = new double[n]; //a[m][n]
		}

		b = new double*[n];  //b[n][k]
		for (i = 0; i < n; i++)
		{
			b[i] = new double[k];//b[n][k]
		}

		c = new double*[m];//c[m][k]
		for (i = 0; i < m; i++)
		{
			c[i] = new double[k];//c[m][k]
		}

	}
	void input();    //从文件读入:a[m][n]与b[n][k]
	void mul();      //执行:a[m][n]*b[n][k]=c[m][k]
	void output();   //输出c[m][k]到文件

	~trmul()   //析构函数 delete空间
	{
		int i;
		for (i = 0; i<m; i++) 
		{ 
			delete[] a[i]; 
		}
		delete[] a;

		for (i = 0; i<n; i++) 
		{ 
			delete[] b[i]; 
		}
		delete[] b;

		for (i = 0; i<m; i++) 
		{ 
			delete[] c[i]; 
		}
		delete[] c;
	}
};

void trmul::input()      //从文件读入矩阵A与B
{
	int  i, j;
	char str1[20];
	//打开方式1:
	//cout << "\n输入文件名:  ";
	//cin >> str1;
	//strcpy(str1,"trmul.dat");
	//ifstream  fin(str1);
	//方式2:
	ifstream  fin;
	fin.open("trmul.dat", ios::in);
	//方式3:
	//ifstream fin("trmul.dat");

	if (!fin)
	{
		cout << "\n不能打开这个文件 " << str1 << endl; 
		exit(1);
	}
	for (i = 0; i < m; i++)                       //读入矩阵A
	{
		for (j = 0; j < n; j++)
		{
			fin >> a[i][j];
		}
	}

	for (i = 0; i < n; i++)                       //读入矩阵B
	{
		for (j = 0; j < k; j++)
		{
			fin >> b[i][j];
		}
	}


	fin.close();
}

void trmul::mul()         //执行a[m][n]*b[n][k]=c[m][k]
{
	int i, j, t;
	for (i = 0; i < m; i++)
	{
		for (j = 0; j<k; j++)
		{
			c[i][j] = 0.0;
			for (t = 0; t < n; t++)
			{
				c[i][j] = c[i][j] + a[i][t] * b[t][j];
			}
		}
	}


}

void trmul::output()       //矩阵C写到文件
{
	int  i, j;
	char str2[20];
	//cout << "\n输出文件名:  ";
	//cin >> str2;
	//ofstream fout(str2);
	strcpy(str2, "out.txt");
	ofstream fout;
	fout.open(str2, ios::out);

	if (!fout)
	{
		cout << "\n不能打开这个文件 " << str2 << endl; 
		exit(1);
	}

	for (i = 0; i<m; i++)
	{
		for (j = 0; j<k; j++)
		{
			//fout << "    " << c[i][j];
			//cout << "    " << c[i][j];
			fout << setw(10) << setprecision(5) << c[i][j];
			cout << setw(10) << setprecision(4) << c[i][j];
		}
		fout << endl; cout << endl;
	}
	fout.close();
}

void main()      //主函数
{
	trmul  c(4, 5, 3);
	c.input();     //从文件读入矩阵A和B
	c.mul();       //执行C=AB
	c.output();    //输出矩阵C到文件
}

说明;

1]

2】文件读取矩阵元素:

A和B矩阵元素放在trmul.dat文件中:

3】输出数据到文件:out.txt

 

矩阵求逆:

 

//实矩阵求逆
#include  <iostream>
#include  <cmath>
#include  <fstream>
using namespace std;
class  rinv
{
private:
	int n;
	double  **a;
public:
	rinv(int nn)
	{
		int i;
		n = nn;
		a = new double*[n];   //动态分配内存空间
		for (i = 0; i < n; i++)
		{
			a[i] = new double[n];
		}

	}
	void input();    //从文件读入矩阵A的元素
	void inv();      //执行求逆运算
	void output();   //输出逆矩阵到文件
	~rinv()          //释放内存空间
	{
		int i;
		for (i = 0; i<n; i++) 
		{ 
			delete[] a[i]; 
		}
		delete[] a;
	}
};

void rinv::input()      //从文件读入矩阵A的元素
{
	int  i, j;
	char str1[20];
	//cout << "\n输入文件名:  ";
	//cin >> str1;
	//ifstream  fin(str1);
	ifstream  fin;
	fin.open("rinv.txt", ios::in);
	strcpy(str1, "rinv.txt");
	if (!fin)
	{
		cout << "\n不能打开这个文件 " << str1 << endl; 
		exit(1);
	}
	for (i = 0; i < n; i++)                       //读入矩阵A
	{
		for (j = 0; j < n; j++)
		{
			fin >> a[i][j];
		}

	}

	fin.close();
}

void rinv::inv()          //执行求逆运算
{
	int *is, *js, i, j, k;
	double d, p;
	is = new int[n];
	js = new int[n];
	for (k = 0; k <= n - 1; k++)
	{
		d = 0.0;
		for (i = k; i <= n - 1; i++)
		for (j = k; j <= n - 1; j++)
		{
			p = fabs(a[i][j]);
			if (p>d) { d = p; is[k] = i; js[k] = j; }
		}
		if (d + 1.0 == 1.0)
		{
			delete[] is, js;
			cout << "\nA为奇异矩阵!没有逆矩阵. " << endl;
			exit(1);
		}
		if (is[k] != k)
		for (j = 0; j <= n - 1; j++)
		{
			p = a[k][j]; a[k][j] = a[is[k]][j]; a[is[k]][j] = p;
		}
		if (js[k] != k)
		for (i = 0; i <= n - 1; i++)
		{
			p = a[i][k]; a[i][k] = a[i][js[k]]; a[i][js[k]] = p;
		}
		a[k][k] = 1.0 / a[k][k];
		for (j = 0; j <= n - 1; j++)
		if (j != k)  a[k][j] = a[k][j] * a[k][k];
		for (i = 0; i <= n - 1; i++)
		if (i != k)
		for (j = 0; j <= n - 1; j++)
		if (j != k) a[i][j] = a[i][j] - a[i][k] * a[k][j];
		for (i = 0; i <= n - 1; i++)
		if (i != k)  a[i][k] = -a[i][k] * a[k][k];
	}
	for (k = n - 1; k >= 0; k--)
	{
		if (js[k] != k)
		for (j = 0; j <= n - 1; j++)
		{
			p = a[k][j]; a[k][j] = a[js[k]][j]; a[js[k]][j] = p;
		}
		if (is[k] != k)
		for (i = 0; i <= n - 1; i++)
		{
			p = a[i][k]; a[i][k] = a[i][is[k]]; a[i][is[k]] = p;
		}
	}
	delete[] is, js;
}

void rinv::output()       //输出逆矩阵到文件
{
	int  i, j;
	char str2[20];
	//cout << "\n输出文件名:  ";
	//cin >> str2;
	//ofstream fout(str2);
	ofstream  fout;
	fout.open("out.txt", ios::in);
	strcpy(str2, "out.txt");
	if (!fout)
	{
		cout << "\n不能打开这个文件 " << str2 << endl; exit(1);
	}
	for (i = 0; i<n; i++)
	{
		for (j = 0; j<n; j++)
		{
			fout << "    " << a[i][j];
			cout << "    " << a[i][j];
		}
		fout << endl;  cout << endl;
	}
	fout.close();
}

void main()      //主函数
{
	rinv  c(4);
	c.input();         //从文件读入矩阵A的元素
	c.inv();           //执行求逆运算
	c.output();        //输出逆矩阵到文件
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章