题目:本题判断二元关系的性质:自反性(reflexive)、对称性(symmetrical)、传递性(transitive)。
输入格式:
输入关系矩阵的阶数n(n<=10),接着输入如具有关系R的元素下标(i,j),输入 -1 -1,结束输入。判断该二元关系具有的性质。
输出格式:
输出二元关系a的性质,如果具有自反性性,则显示“a is reflexive”,如果具有对称性,则显示“a is transitive”,如果具有传递性,则显示“a is transitive”,如果具有自反性、对称性、传递性,则显示具有等价性“a is equivalent”。如果输入的n大于10,或者输入的数组元素下标i,j大于等于n(数组元素的下标应小于n),则显示"error",并结束程序。注意每个显示前后无空格,末尾回车。
输入样例:
在这里给出一组输入。例如:
3 1 0 2 0 0 1 2 1 0 2 1 2 -1 -1
输出样例:
在这里给出相应的输出。例如:
a is symmetrical
一、知识点说明:
一直以来用关系图理解自反对称传递等性质,放到关系矩阵中我就懵了
首先:关系图中有n个点 ,关系矩阵就用 n阶矩阵
其次:三种性质都是蕴含式
注意:记关系图中各点依次 为1,2,3....;关系矩阵中,有向边(关系)则用(i, j)表示
最后:三种性质特点(题目只考察自反对称传递,这里先不提反自反,反对称)
1.自反性:
关系图,每个顶点都有环,则矩阵中表示(a, a)[即:有从该点自身到自身的有向边]
关系矩阵,n阶矩阵,主对角线元素全为1.
2.对称性:
关系图:如果两个顶点之间有边,则一定是一对方向相反的边
(注意:这是蕴含式,如果前件不成立,两点之间连边都没有,同样满足对称性)
关系矩阵:存在关系(a,b)且存在关系(b,a),即:矩阵为对称矩阵
3.传递性:
关系图:如果顶点a到b有边,b到c有边,则a到c有边
(同样注意:蕴含式,如果前件不成立,即不满足"a到b有边,且b到c有边",也满足传递性)
关系矩阵:如果存在关系(a,b)且(b,c),则存在关系(a,c)
二、代码:(分别用函数判断)
最开始想着函数判断思路可能会更清晰,后来发现同学的代码不用函数更简洁
#include<iostream>
using namespace std;
//1:判断自反性函数 :
bool Reflexive(int ARR[10][10], int n)
{
int a1 = 0;//定义一个计数器,用于记录对角线为1的元素个数
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= n; j++)
{
if (ARR[i][j] == 1)//为1 的元素进入,准备判断各种性质
{
if (i == j)//其实两个条件可以合并
{
a1++;//满足自反的元素个数
}
}
}
}
if ( a1 == n)
{
return 1;//满足自反性,返回1
}
else
{
return 0;//不满足自反
}
}
//2:判断对称性函数
bool Symmetrical(int ARR[10][10], int n)
{
int B = 0;//记录关系数
int b= 0;//记录满足对称性的关系数目
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= n; j++)
{
if (ARR[i][j] == 1)
{
B++;//(1,1)这种对角线关系,也满足对称性定义
if (ARR[i][j] == 1 && ARR[j][i] == 1)
{
b++;//两个顶点间是双向边,则记录
}
}
}
}
if (b== B )//存在关系<i,j>,且存在<j,i>,双向边,则b==B
{
return 1;//满足对称
}
else
{
return 0;//不对称
}
}
//3:判断传递性函数 :
bool Transitive(int ARR[10][10], int n)
{
int C1 = 0;
int c1 = 0;
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= n; j++)
{
if (ARR[i][j] == 1)//为1 的元素进入,准备判断各种性质
{
for (int k = 0; k <= n; k++) //用于(j,k)
{
if (ARR[j][k] == 1)
{
C1++;//记录前件“顶点a到b有边,且b到c有边” 的次数
if (ARR[i][k] == 1)
{
c1++;//记录后件“a到c有边”的次数
}
}
}
}
}
}
if (c1 == C1 || C1 == 0)//前件后件均成立,顶点a到b有边,b到c有边,且a到c有边,则蕴含式为真,满足传递(c1==C1);或者蕴含式前件都不满足,即不存在“顶点a到b有边,且b到c有边”,蕴含式也为真,亦满足传递性(C1==0);
{
return 1;//满足传递性
}
else
{
return 0;//不满足传递性
}
}
int main()
{
//一:输入元素阶数n,以及元素关系(a,b),初始化关系 为1
int arr[10][10] = { 0 };
int n, a = 0, b = 0;
cin >> n;
while (a != -1 && b != -1)//输入(-1,-1)时,结束输入
{
cin >> a >> b;
if (n > 10 || a >= n || b >= n)//解决题目中[如果输入的n大于10,或者输入的数组元素下标i,j大于等于n(数组元素的下标应小于n),则显示"error",并结束程序。]问题
{
cout << "error";
return 0;
}
arr[a][b] = 1;//初始化该关系为1
}
//二:调用函数判断并输出性质
int A, B, C;//记录性质,满足对应性质为1,不满足为0
A = Reflexive(arr, n);
B = Symmetrical(arr, n);
C = Transitive(arr, n);
//这题输出格式,满足几条性质就输出几条性质;三种均满足,则输出三条性质外,还需格外输出等价性。
if (A == 1)
{
cout << "a is reflexive" << endl;
}
if (B == 1)
{
cout << "a is symmetrical" << endl;
}
if (C == 1)
{
cout << "a is transitive" << endl;
}
if (A == 1 && B == 1 && C == 1)//三种性质均满足,格外输出等价性
{
cout << "a is equivalent";
}
}
有空了重做,简化了再来