编程实现任意集合上任意二元关系的判定。 要求能正确判断二元关系的自反性、传递性、对称性、反自反性、反对称性。
显然,我们首先要做到的就是怎么样判断这些二元关系的性质。我想到的方法有两种:
- 使用性质的定义来判断。
- 使用性质在矩阵上具有的特点来判断。
显然,使用第一种方法将定义转换为代码复杂。而使用矩阵特征易于实现。因此选择第二种方法。
创建动态二维数组以存储矩阵中的元素(0/1),允许手动输入矩阵元素来满足任意二元关系的要求。
在循环体外定义标记变量value1,value2实现在循环结束后在体外判断判断的目的。传递性的判断使用沃什算法实现(注意沃什算法的“+”号代表逻辑加)
下面是我写的程序:
#include<iostream>
#include<malloc.h>
using namespace std;
int main()
{
int n=0;
cout<<"请输入矩阵维度n"<<endl;
cin>>n;
int **p;
p=(int **)malloc( n*sizeof(int *)); //定义第一列
for(int i=0;i<n;i++)
p[i]=(int *)malloc(n*sizeof(int )); //定义行
int **q;
q=(int **)malloc( n*sizeof(int *)); //定义第一列
for(i=0;i<n;i++)
q[i]=(int *)malloc(n*sizeof(int )); //定义行
cout<<"请输入矩阵元素0/1"<<endl;
for(i=0;i<n;i++)
for(int j=0;j<n;j++)
{
cin>>p[i][j];
}
//输入矩阵元素
for(i=0;i<n;i++)
for(int j=0;j<n;j++)
{
cout<<p[i][j];
if(j==n-1)
cout<<endl;
}
//输出矩阵元素
int value1=0, value2=0;i=0;//每次判断前重置循环变量
while(i<n)
{
if(p[i][i]==1)
value2++;
else
value1++;
i++;
};
if(value1==n)
cout<<"反自反性"<<endl;
if(value2==n)
cout<<"自反性"<<endl;
if(value1==n&&value2==n)
cout<<"自反性也有反自反性"<<endl;
if(value1!=n&&value2!=n)
cout<<"没有自反性和反自反性"<<endl;
value1=0;value2=0;i=0;//重置判断标志
for(i=0;i<n;i++)
for( int j=0;j<n;j++)
{
if(p[i][j]==p[j][i])
value1++;
else
value2++;
}
if(value1==n*n)
cout<<"对称性"<<endl;
if(value2==n*n)
cout<<"反对称性"<<endl;
if(value1!=n*n&&value2!=n*n)
cout<<"无对称性也无反对称性"<<endl;
for(i=0;i<n;i++)
{
for(int j=0;j<n;j++)
q[i][j]=p[i][j];//置新矩阵q=p
}
cout<<"Matrix q[i][j]:"<<endl;
for(i=0;i<n;i++)
for(int j=0;j<n;j++)
{
cout<<q[i][j];
if(j==n-1)
cout<<endl;
}
//输出矩阵元素q[i][j]
bool flag=false;
for(int m=0;m<n;m++)
for(i=0;i<n;i++)
if(q[i][m]==1)
{
for(int j=0;j<n;j++)
{
if(2==(q[i][j]+q[m][j]))
q[i][j]=1;
else
q[i][j]=q[i][j]+q[m][j];
}
}
int h=0;
for(i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(q[i][j]!=p[i][j])
{
cout<<"无传递性"<<endl;
flag=true;
break;
}
else
h++;
}
if(flag==true)
break;//跳出外层循环
}
cout<<h<<endl<<endl;
if(h==n*n)
cout<<"有传递性"<<endl;
return 0;
}
程序中没有进行输入判断,导致其健壮性不足。当然集合元素也可改成键盘输入,再得到对应的矩阵,我就小小的偷下懒了