(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();        //輸出逆矩陣到文件
}

 

 

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