判断二元关系的性质:自反性、对称性、传递性

题目:本题判断二元关系的性质:自反性(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";
		}

	}

有空了重做,简化了再来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值