今天复盘了一下之前写的一个离散课实验,记录一下编写的思路。
首先我们来说说序偶和关系:
序偶可以看作是具有两个元素的集合。但它与一般集合不同的是序偶具有确定的次序。在集合中{a,b}={b,a),但对序偶<a,b>!=<b,a>。
关系是一个基本概念,在日常生活中我们都熟悉关系这词的含义,例如兄弟关系;上下级关系;位置关系等。在数学上关系可表达集合中元素间的联系。例如,“3小于 5”;“z大于y”,“点a在b与c之间”等。我们又知道,序偶可以表达两个客体、三个客体或n个客体之间的联系,因此用序偶表达关系这个概念是非常自然的。
介绍完了序偶和关系,那序偶和关系之间的具体联系又是什么呢?
任一序偶的集合确定了一个二元关系R,R中
任一序偶<x,y>可记作<x,y>ER或xRy。不在R中的任一序偶<x,y>可记作<x,y> /ER或x\Ry。 (因为手机限制,部分符号只能根据字母与普通符号代替,具体符号请见下图)
关系的表示方法有很多,但为了铺垫实验中涉及到的关系的矩阵表示与矩阵计算,在这里简单描述一下关系的矩阵表示,不太理解的话大家可以去详细的搜一搜关于关系的矩阵表示以及矩阵计算。
关系矩阵:将R中的有序对<a_i,b_j>用矩阵中对应的<i,j>位置=1来表示。比如集合A中含有三个元素,A={1,2,3},R是A上的一个关系,R={<1, 2>, <1,3>, <2, 3>}, 那么R的关系矩阵就是一个3*3的矩阵:
0 1 1
0 0 1
0 0 0
下面我们就进入正题,说一说关系的复合运算以及逆运算该如何用代码实现
实验要求:用代码实现关系的复合运算和逆运算并输出
输入格式:首先输入关系所在集合的元素个数及其元素,然后输入建立在该集合上的两个关系序偶;
输出格式:复合后以及取逆后的关系序偶。
实验思路:我们首先将集合存入数组,明确我们要建立一个n*n的数组,然后根据输入格式的特殊性,读取数字储存表示行和表示列的数组。在这里要注意char与int的不同以及二维数组的下标从零开始。
实验代码:
#include <stdio.h>
#include <string.h>
int main(){
printf("请输入集合A的元素个数:\n");
int n;
scanf("%d",&n);
int a[n];
printf("请输入A中的元素:\n");
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
printf("请输入集合A上的关系R(关系序偶输入格式为{<a,b>,<c,d>……}):\n");
char c[10000];
scanf("%s",c);
printf("请输入集合A上的另一关系S(关系序偶输入格式为{<a,b>,<c,d>……}):\n");
char d[10000];
scanf("%s",d);
int m=n;
int s1=strlen(c);
int h1[1000],l1[1000];
//第一个关系序偶矩阵化的处理
int i=0,j=0,k=0;
for(i=0;i<s1;i++){
if(c[i]<='9'&&c[i]>='0'&&c[i+1]==',')
h1[j++]=c[i]-'0';
if(c[i]<='9'&&c[i]>='0'&&c[i+1]!=',')
l1[k++]=c[i]-'0';}
int s2=strlen(d);
int h2[1000],l2[1000];
//第二个关系序偶矩阵化的处理
int p=0,q=0,r=0;
for(p=0;p<s2;p++){
if(d[p]<='9'&&d[p]>='0'&&d[p+1]==',')
h2[q++]=d[p]-'0';
if(d[p]<='9'&&d[p]>='0'&&d[p+1]!=',')
l2[r++]=d[p]-'0';}
int juzhen1[n][n],juzhen2[m][m];
for(int i=0;i<n;i++){
for(int j=0;j<n;j++)
{juzhen1[i][j]=0;}}
for(int i=0;i<m;i++){
for(int j=0;j<m;j++)
juzhen2[i][j]=0;}
for(int i=0,x=0;i<j;i++,x++)
juzhen1[h1[x]-1][l1[x]-1]=1;
for(int i=0,x=0;i<q;i++,x++)
juzhen2[h2[x]-1][l2[x]-1]=1;
int juzhen3[n][m];
for(int i=0;i<j;i++)
int sum;
//矩阵计算
for(int i=0;i<n;i++)
{for(int j=0;j<m;j++)
{int sum=0;
for(int k=0;k<n;k++)
{
sum+=juzhen1[i][k]*juzhen2[k][j];
}
juzhen3[i][j]=sum;
}
}
int h3[100],l3[100];
int e=0,f=0;
for(int i=0;i<n;i++)
{for(int j=0;j<n;j++)
if(juzhen3[i][j]>0)
{h3[e++]=i;
l3[f++]=j;}
}
printf("R复合S为:\n");
printf("{");
for(int i=0,j=0;i<e;i++)
{printf("<%d,%d>",h3[i]+1,l3[i]+1);
j++;
if(j<=e-1)
printf(",");}
printf("}\n");
printf("R的逆关系为:\n");
printf("{");
for(int i=0,k=0;i<j;i++)
{printf("<%d,%d>",l1[i],h1[i]);
k++;
if(k<=j-1)
printf(",");}
printf("}\n");
printf("S的逆关系为:\n");
printf("{");
for(int i=0,k=0;i<q;i++)
{printf("<%d,%d>",l2[i],h2[i]);
k++;
if(k<=q-1)
printf(",");}
printf("}\n");
return 0;}
实验反思:写这个实验的时候还没有学过线性代数,对于矩阵乘法还是不熟练,浪费了很多时间。
好久没有写代码了,很多地方写的还有很多问题,希望大家看到后能指出来或者有优化方案的话也可以在评论区告诉我。
创作不易,点个赞再走吧^-^!