通过离散数学的实验,可以进一步运用new运算符,复制构造函数,析构函数等C++类中的基础知识;同时提供了一个验证传递性的方法,化特殊到一般,把任何形式关系矩阵统统转换为方阵(基于善意的判断这一概念)从而实现验证传递性。(基于VS2010)
#include<iostream>
#include<iomanip>//控制格式化输出
using namespace std;
class Matrix//利用关系矩阵判断关系的性质
{
private:
int **Mr;//关系矩阵 利用二级指针建立动态的二维数组表示序偶对是否属于关系R
int r,c;//关系矩阵的行和列
public:
Matrix(int r=0,int c=0);
Matrix(const Matrix &M);
~Matrix();
void print();
void judgeR();
void judgeS();
void judgeT();
void judgeAR();
void judgeAS();
};
Matrix::Matrix(int n,int m):r(n),c(m)
{
Mr=new int *[r];
for(int i=0;i<r;i++)//这里理解了一个bug :HEAP CORRUPTION DETECTED 内存溢出错误 需要注意所构建的动态空间是否
Mr[i]=new int [m];//被给予了超出这个空间的数
cout<<"请输入矩阵元素(属于关系R输入1/不属于关系R输入0):"<<endl;
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
cin>>Mr[i][j];
}
}
}
Matrix::Matrix(const Matrix &M)
{
r=M.r;
c=M.c;
if(!Mr)
{
for(int i=0;i<r;i++)
delete []Mr[i];
delete []Mr;
}
Mr=new int* [r];
for(int i=0;i<r;i++)
{
Mr[i]=new int [c];
}
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
Mr[i][j]=M.Mr[i][j];
}
}
}
Matrix::~Matrix()
{
for(int i=0;i<r;i++)
delete []Mr[i];
delete []Mr;
}
void Matrix::judgeR()
{
if(r==c)//自反性必须是方阵
{
for(int i=0;i<r;i++)
{
if(Mr[i][i]==1)
continue;
else
{
cout<<"R不具有自反性!"<<endl;
return;
}
}
}
else
{
cout<<"R不具有自反性!"<<endl;
return;
}
cout<<"R具有自反性!"<<endl;
return;
}
void Matrix::judgeAR()
{
if(r==c)//反自反性必须是方阵
{
for(int i=0;i<r;i++)
{
if(Mr[i][i]==0)
continue;
else
{
cout<<"R不具有反自反性!"<<endl;
return;
}
}
}
else
{
cout<<"R不具有反自反性!"<<endl;
return;
}
cout<<"R具有反自反性!"<<endl;
return;
}
void Matrix::judgeS()
{
if(r==c)//对称性必须是方阵
{
for(int i=0;i<r;i++)
{
for(int j=0;j<r;j++)
{
if(Mr[i][j]==Mr[j][i])//包含了正常情况也包含善意的判断
continue;
else
{
cout<<"R不具有对称性!"<<endl;
return;
}
}
}
}
else
{
cout<<"R不具有对称性!"<<endl;
return;
}
cout<<"R具有对称性!"<<endl;
return;
}
void Matrix::judgeAS()
{
if(r==c)//反对称性必须是方阵
{
for(int i=0;i<r;i++)
{
for(int j=0;j<r;j++)
{
if(i==j)
continue;
else
{
if((Mr[i][j]*Mr[j][i])==0)//包含了正常情况也包含善意的判断
continue;
else
{
cout<<"R不具有反对称性!"<<endl;
return;
}
}
}
}
}
else
{
cout<<"R不具有反对称性!"<<endl;
return;
}
cout<<"R具有反对称性!"<<endl;
return;
}
void Matrix::judgeT()//常规思路是一个一个元素遍历,但是由于关系矩阵是动态的二维数组,使用遍历的方法可能会导致数组越界,还有随机数的问题,但是对于方阵
//我们可以利用计算机很好的判断传递性,因此我们选择把动态的二维数组转换为方阵去判断其对称性(借助善意的判断去重置元素)
{
int num=(r>c?r:c);//选择行列中较大的那一个作为方阵的阶数
int **Mr1;
Mr1=new int*[num];
for(int i=0;i<num;i++)
{
Mr1[i]=new int[num];
}
for(int i=0;i<num;i++)
{
for(int j=0;j<num;j++)
{
Mr1[i][j]=0;//默认不存在的元素为(善意的判断)
}
}
for(int i=0;i<r;i++)//重置关系矩阵中的元素
{
for(int j=0;j<c;j++)
{
Mr1[i][j]=Mr[i][j];//和原有矩阵构建联系
}
}
for(int i=0;i<num;i++)
{
for(int j=0;j<num;j++)
{
for(int k=0;k<num;k++)
{
if((Mr1[i][j]*Mr1[j][k])==1&&(Mr1[i][k]==1))
continue;
else if(Mr1[i][j]*Mr1[j][k]==0)
continue;
else
{
cout<<"R不具有传递性!"<<endl;
for(int i=0;i<num;i++)
{
delete []Mr1[i];
}
delete []Mr1;
return;
}
}
}
}
cout<<"R具有传递性!"<<endl;
for(int i=0;i<num;i++)
{
delete []Mr1[i];
}
delete []Mr1;
return;
}
void Matrix::print()//打印关系矩阵
{
cout<<"R的关系矩阵为:"<<endl;
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
cout<<setw(5)<<Mr[i][j];
if(j==(c-1))
{
cout<<endl;
}
}
}
}
int main()
{
int An,Bn;
cout<<"请输入A,B中元素个数:";
cin>>An>>Bn;
Matrix R(An,Bn);
R.print();
R.judgeR();
R.judgeAR();
R.judgeS();
R.judgeAS();
R.judgeT();
return 0;
}