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