(C++ )矩阵
2015-11-01 18:18
363 查看
template<class T> class matrix
{
public:
matrix(int r=0,int c=0);
matrix(matrix<T>&m);
~matrix(){ delete[]melem;}
void input();
void output();
T & operator()(int i,int j);
matrix<T>&operator=(matrix<T>&m);
matrix<T>operator+(matrix<T>&m);
matrix<T>operator-(matrix<T>&m);
matrix<T>operator*(matrix<T>&m);
void transmat(matrix<T>&b,matrix<T>&a);
private:
int rows,cols;
T *melem;
};
template<class T> matrix<T>::matrix(int r,int c)
{
rows=r;
cols=c;
melem=new T[r*c];
}
template<class T> matrix<T>::matrix(matrix<T>&m)
{
rows=m.rows;
cols=m.cols;
melem=new T[rows*cols];
for(int i=0;i<rows*cols;i++)
melem[i]=m.melem[i];
}
template<class T> matrix<T>& matrix<T>::operator=(matrix<T>&m)
{
rows=m.rows;
cols=m.cols;
melem=new T[rows*cols];
for(int i=0;i<rows*cols;i++)
melem[i]=m.melem[i];
return *this;
}
template<class T>T & matrix<T>::operator()(int i,int j)
{
return melem[(i-1)*cols+j-1];
}
template<class T> matrix<T>matrix<T>::operator+(matrix<T>&m)
{
if(rows!=m.rows||cols!=m.cols)
{
cout<<"不符合加法规则,结束操作!"<<endl;
return -1;}
matrix<T> c(rows,cols);
for(int i=0;i<rows*cols;i++)
c.melem[i]=melem[i]+m.melem[i];
return c;
}
/*要实现矩阵乘法,需要3层循环,最里的循环用来计算第i行乘以第j列,例如第1行乘以第一列,ca会移动到行尾,(ca+1为同行的下一个元素,
cb+m.cols为列的下一个元素位置),接下来计算第一行乘以第二列,所以将ca移动行首(ca=ca-cols-1),将cb指向第二列(cb=j),按此计算
直到完成最外一层循环*/
template<class T> matrix<T>matrix<T>::operator*(matrix<T>&m)
{
if(cols!=m.rows){
cout<<"不符合乘法规则,结束操作!"<<endl;/*检查是否符合矩阵乘法原则*/
return -1;}
matrix<T>c(rows,m.cols);
int ca=0,cb=0,cc=0;
for(int i=1;i<=rows;i++){ /*最外层循环,行元素*/
for(int j=1;j<=cols;j++){/*列元素循环*/
T sum=melem[ca]*m.melem[cb];/*计算第一个行元素与对应列第一个元素的乘机,所以下面的循环从2开始到cols*/
for(int k=2;k<=cols;k++)/*完成行、列相应元素相乘的功能*/
{
ca++;
cb+=m.cols;
sum+=melem[ca]*m.melem[cb];
}
c.melem[cc++]=sum;/*保存*/
ca-=cols-1;/*调整至行头*/
cb=j;/*调整至下一列*/
}
ca+=cols;/*调整至下一行行头*/
cb=0;/*调整至第一列*/
}
return c;
}
template<class T> void matrix<T>::input()
{
for(int i=0;i<rows*cols;i++)
cin>>melem[i];}
template<class T> void matrix<T>::output()
{
for(int i=0;i<rows*cols;i++)
{
if(i%cols==0)
cout<<endl;
cout<<melem[i]<<" ";
}
cout<<endl;
}
template<class T>void matrix<T>::transmat(matrix<T>&b,matrix<T>&a)
{
int i,j;
for(i=0;i<rows;i++)
for(j=0;j<cols;j++)
a(i,j)=b(j,i);
}
以下为测试函数:
#include<iostream>
#include"smatrix.h"
using namespace std;
void main()
{
matrix<int> A(3,4),B(4,3),C(3,3),E(3,4);
cout<<"input A:\n";
A.input();
cout<<"input B:\n";
B.input();
C=A*B;
cout<<"C=A*B";C.output();
matrix<int>D(C);
D=D+C;
cout<<"D=D+C";D.output();
B.transmat(B,E);
cout<<"转置B-E";
E.output();
}
如果在矩阵中存在一个元素A[i][j],满足它是第i行元素中最小值,且又是第j列元素中的最大值,则称之元素为该矩阵的一个马鞍点。试编写求出矩阵中所有马鞍点的算法。
分析;按照题意,先求出每行中的最小值元素,存入数组min[m],再求出每列的最大值元素,存入数组max
,若某元素即在min中又在max中,即为马鞍点
template<class T>void maxmin(matrix<T>A)
{
int i,j n,m,k=0;
m=A.rows;n=A.cols;
T *max=new T[m+1];
T *min=new T[n+1];
for(i=1;i<=m;i++){
min[i]=A(i,1);
for(j=1;j<=n;j++)
if(A(i,j)<min[i])
min[i]=A(i,j);
}
for(j=1;j<=n;j++)
{
max[j]=A(1,j);
for(i=1;i<=m;i++)
if(A(i,j)>max[j])
max[j]=A(i,j);
}
for(i=1;i<=m;i++)
for(j=1;j<=n;j++)
if(max[j]==min[i]){
cout<<"max("<<i<<","<<j<<")="<<max[j]<<",是马鞍点"<<endl;
k=1;}
if(k==0)
cout<<"无马鞍点"<<endl;
}
特殊矩阵:
1.三角矩阵有上三角矩阵和下三角矩阵
为了节省存储的空间,我们可以用一维数组来存储,下面以下三角为例:
template<class T>class lowermatrix
{
public:
lowermatrix(int maxsize=10){
n=maxsize;M=new T[n*(n+1)/2];
}
T getdata(int i,int j);
void input();
void print();
private:
int n;
T *M;
};
template<class T> T lowermatrix<T>::getdata(int i,int j)
{
if(i>=j)
return M[i*(i-1)/2+j-1];
else
return 0;
}
template<class T> void lowermatrix<T>::input()
{
for(int i=0;i<=n*(n+1)/2-1;i++)
cin>>M[i];
}
template<class T> void lowermatrix<T>::print()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)
cout<<getdata(i,j)<<" ";
cout<<endl;
}
}
使用上述类定义实现创建一个5阶的下三角矩阵输入、输出元素等操作
#include<iostream>
#include"lowermatrix.h"
using namespace std;
void main()
{
lowermatrix<int>t(5);
t.input();
t.print();
cout<<endl;
}
对称矩阵:
对称矩阵中的元素关于主对角线对称,所以只需要存储矩阵中上三角或下三角的元素即可,让两个对称的元素共享一个存储空间。用一维数组数组来存储对称矩阵,
1.i>>j时,则元素在下三角矩阵中
2.i<j时,则元素在上三角矩阵中
template<class T> void matrixmult(lowermatrix<T>a,lowermatrix<T>b,T c[5][5])
{
int i,j,k,11,12;
for(i=1;i<=a.n;i++)
for(j=1;j<=a.n;j++){
int s=0;
for(k=1;k<=a.n;k++){
if(i>=k)
11=i*(i-1)/2+k-1; /*表示元素为下三角的元素,计算在a数组中的下标*/
else
11=k*(k-1)/2+i-1; /*表示元素为上三角的元素,计算在a数组中的下标*/
if(k>=j)
12=k*(k-1)/2+j-1; /*表示元素为下三角的元素,计算在b数组中的下标*/
else
12=j*(j-1)/2+k-1; /*表示元素为上三角的元素,计算在b数组中的下标*/
s=s+a.M[11]*b.M[12];
}
c[i-1][j-1]=s;
}
}
稀疏矩阵:其中有s个非零元素,而s远远小于矩阵元素的总数,称为稀疏矩阵,为了节省存储单元,也可用压缩存储的方法只存储非零元素。由于稀疏矩阵非零分布一般是没有规律的,因此,在存储非零元素的时候,除了存储非零元素的值之外,还必须同时存储该元素的行、列位置,所以可用一个三元组来唯一确定一个非零元素。
{
public:
matrix(int r=0,int c=0);
matrix(matrix<T>&m);
~matrix(){ delete[]melem;}
void input();
void output();
T & operator()(int i,int j);
matrix<T>&operator=(matrix<T>&m);
matrix<T>operator+(matrix<T>&m);
matrix<T>operator-(matrix<T>&m);
matrix<T>operator*(matrix<T>&m);
void transmat(matrix<T>&b,matrix<T>&a);
private:
int rows,cols;
T *melem;
};
template<class T> matrix<T>::matrix(int r,int c)
{
rows=r;
cols=c;
melem=new T[r*c];
}
template<class T> matrix<T>::matrix(matrix<T>&m)
{
rows=m.rows;
cols=m.cols;
melem=new T[rows*cols];
for(int i=0;i<rows*cols;i++)
melem[i]=m.melem[i];
}
template<class T> matrix<T>& matrix<T>::operator=(matrix<T>&m)
{
rows=m.rows;
cols=m.cols;
melem=new T[rows*cols];
for(int i=0;i<rows*cols;i++)
melem[i]=m.melem[i];
return *this;
}
template<class T>T & matrix<T>::operator()(int i,int j)
{
return melem[(i-1)*cols+j-1];
}
template<class T> matrix<T>matrix<T>::operator+(matrix<T>&m)
{
if(rows!=m.rows||cols!=m.cols)
{
cout<<"不符合加法规则,结束操作!"<<endl;
return -1;}
matrix<T> c(rows,cols);
for(int i=0;i<rows*cols;i++)
c.melem[i]=melem[i]+m.melem[i];
return c;
}
/*要实现矩阵乘法,需要3层循环,最里的循环用来计算第i行乘以第j列,例如第1行乘以第一列,ca会移动到行尾,(ca+1为同行的下一个元素,
cb+m.cols为列的下一个元素位置),接下来计算第一行乘以第二列,所以将ca移动行首(ca=ca-cols-1),将cb指向第二列(cb=j),按此计算
直到完成最外一层循环*/
template<class T> matrix<T>matrix<T>::operator*(matrix<T>&m)
{
if(cols!=m.rows){
cout<<"不符合乘法规则,结束操作!"<<endl;/*检查是否符合矩阵乘法原则*/
return -1;}
matrix<T>c(rows,m.cols);
int ca=0,cb=0,cc=0;
for(int i=1;i<=rows;i++){ /*最外层循环,行元素*/
for(int j=1;j<=cols;j++){/*列元素循环*/
T sum=melem[ca]*m.melem[cb];/*计算第一个行元素与对应列第一个元素的乘机,所以下面的循环从2开始到cols*/
for(int k=2;k<=cols;k++)/*完成行、列相应元素相乘的功能*/
{
ca++;
cb+=m.cols;
sum+=melem[ca]*m.melem[cb];
}
c.melem[cc++]=sum;/*保存*/
ca-=cols-1;/*调整至行头*/
cb=j;/*调整至下一列*/
}
ca+=cols;/*调整至下一行行头*/
cb=0;/*调整至第一列*/
}
return c;
}
template<class T> void matrix<T>::input()
{
for(int i=0;i<rows*cols;i++)
cin>>melem[i];}
template<class T> void matrix<T>::output()
{
for(int i=0;i<rows*cols;i++)
{
if(i%cols==0)
cout<<endl;
cout<<melem[i]<<" ";
}
cout<<endl;
}
template<class T>void matrix<T>::transmat(matrix<T>&b,matrix<T>&a)
{
int i,j;
for(i=0;i<rows;i++)
for(j=0;j<cols;j++)
a(i,j)=b(j,i);
}
以下为测试函数:
#include<iostream>
#include"smatrix.h"
using namespace std;
void main()
{
matrix<int> A(3,4),B(4,3),C(3,3),E(3,4);
cout<<"input A:\n";
A.input();
cout<<"input B:\n";
B.input();
C=A*B;
cout<<"C=A*B";C.output();
matrix<int>D(C);
D=D+C;
cout<<"D=D+C";D.output();
B.transmat(B,E);
cout<<"转置B-E";
E.output();
}
如果在矩阵中存在一个元素A[i][j],满足它是第i行元素中最小值,且又是第j列元素中的最大值,则称之元素为该矩阵的一个马鞍点。试编写求出矩阵中所有马鞍点的算法。
分析;按照题意,先求出每行中的最小值元素,存入数组min[m],再求出每列的最大值元素,存入数组max
,若某元素即在min中又在max中,即为马鞍点
template<class T>void maxmin(matrix<T>A)
{
int i,j n,m,k=0;
m=A.rows;n=A.cols;
T *max=new T[m+1];
T *min=new T[n+1];
for(i=1;i<=m;i++){
min[i]=A(i,1);
for(j=1;j<=n;j++)
if(A(i,j)<min[i])
min[i]=A(i,j);
}
for(j=1;j<=n;j++)
{
max[j]=A(1,j);
for(i=1;i<=m;i++)
if(A(i,j)>max[j])
max[j]=A(i,j);
}
for(i=1;i<=m;i++)
for(j=1;j<=n;j++)
if(max[j]==min[i]){
cout<<"max("<<i<<","<<j<<")="<<max[j]<<",是马鞍点"<<endl;
k=1;}
if(k==0)
cout<<"无马鞍点"<<endl;
}
特殊矩阵:
1.三角矩阵有上三角矩阵和下三角矩阵
为了节省存储的空间,我们可以用一维数组来存储,下面以下三角为例:
template<class T>class lowermatrix
{
public:
lowermatrix(int maxsize=10){
n=maxsize;M=new T[n*(n+1)/2];
}
T getdata(int i,int j);
void input();
void print();
private:
int n;
T *M;
};
template<class T> T lowermatrix<T>::getdata(int i,int j)
{
if(i>=j)
return M[i*(i-1)/2+j-1];
else
return 0;
}
template<class T> void lowermatrix<T>::input()
{
for(int i=0;i<=n*(n+1)/2-1;i++)
cin>>M[i];
}
template<class T> void lowermatrix<T>::print()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)
cout<<getdata(i,j)<<" ";
cout<<endl;
}
}
使用上述类定义实现创建一个5阶的下三角矩阵输入、输出元素等操作
#include<iostream>
#include"lowermatrix.h"
using namespace std;
void main()
{
lowermatrix<int>t(5);
t.input();
t.print();
cout<<endl;
}
对称矩阵:
对称矩阵中的元素关于主对角线对称,所以只需要存储矩阵中上三角或下三角的元素即可,让两个对称的元素共享一个存储空间。用一维数组数组来存储对称矩阵,
1.i>>j时,则元素在下三角矩阵中
2.i<j时,则元素在上三角矩阵中
template<class T> void matrixmult(lowermatrix<T>a,lowermatrix<T>b,T c[5][5])
{
int i,j,k,11,12;
for(i=1;i<=a.n;i++)
for(j=1;j<=a.n;j++){
int s=0;
for(k=1;k<=a.n;k++){
if(i>=k)
11=i*(i-1)/2+k-1; /*表示元素为下三角的元素,计算在a数组中的下标*/
else
11=k*(k-1)/2+i-1; /*表示元素为上三角的元素,计算在a数组中的下标*/
if(k>=j)
12=k*(k-1)/2+j-1; /*表示元素为下三角的元素,计算在b数组中的下标*/
else
12=j*(j-1)/2+k-1; /*表示元素为上三角的元素,计算在b数组中的下标*/
s=s+a.M[11]*b.M[12];
}
c[i-1][j-1]=s;
}
}
稀疏矩阵:其中有s个非零元素,而s远远小于矩阵元素的总数,称为稀疏矩阵,为了节省存储单元,也可用压缩存储的方法只存储非零元素。由于稀疏矩阵非零分布一般是没有规律的,因此,在存储非零元素的时候,除了存储非零元素的值之外,还必须同时存储该元素的行、列位置,所以可用一个三元组来唯一确定一个非零元素。
相关文章推荐
- 你应当如何学习C++(以及编程)(rev#1)
- C++与linus
- 像原生C/C++,序列化Java对象
- c++笔记之赋值函数,拷贝构造函数,构造函数,析构函数
- C学习笔记——接触C语言
- hdu5532Almost Sorted Array(长春现场赛)
- C语言解释器Java版-0-内存模型
- 图的存储结构——邻接矩阵(算法简介/c++实现)
- 犯过的C++错误: vector::swap()函数
- 1.初识c语言
- c语言之指针与数组理解一(数据拷贝)
- 快速幂取模详解(C语言版)
- C++ 读写注册表
- C++ 读写注册表
- 学习笔记-多项式的加减乘数及微分的C++实现15/11/02
- 【笔试题】C语言:在字符串中找出第一个只出现一次的字符。如输入“abaccdeff”,则输出'b'。
- C++中修改文件夹名以及文件名
- C++中修改文件夹名以及文件名
- c语言之sizeof 与 strlen理解
- 【转载】深入理解c++的右值引用