离散数学实验之求解关系的闭包运算

 

我自己写不这么好,说实在的,我也写不出来。这是老师给我们的一个代码。我把他在这上面保存下来,以后可能能用的到。

关系闭包运算
    1、输入构建关系的结点;
    2、程序对结点进行排序,以构造出符合人们表示习惯的关系矩阵;
    3、根据输入的结点输入关系的序偶;
    4、选择命令,执行相应计算。 

/**********************************************************************************
   ***********关系闭包运算***********
				1、输入构建关系的结点;
				2、程序对结点进行排序,以构造出符合人们表示习惯的关系矩阵;
				3、根据输入的结点输入关系的序偶;
				4、选择命令,执行相应计算。									  
***********************************************************************************/
#include<stdio.h>
#include<conio.h>
#include<string.h>
#define M  100

char *get_element(char *p)//输入结点序列函数
{
    printf("第一步:输入各个结点的名称后回车(不能有空格):");
    gets(p);
    fflush(stdin);
    return p;
}

void str_sort(char *point)//将结点重新按照其ASCII码排序,如d3jkab排列为3abdjk
                          //关系矩阵将根据此顺序来构造
{
    char *p=point,*q,t;
    int stlen=strlen(p);
    for(p=point;p<point+stlen-1;p++)//选择排序
        for(q=p+1;*q;q++)
            if(*p>*q){t=*p;*p=*q;*q=t;}
            printf("重新排序后的结点序列为:");
            for(p=point;*p;p++)putchar(*p);printf("\n"); //输出排序后的字符
}

int get_position(char ch,char *point)//函数返回字符(结点)ch在point中的位置
{
    int i;
    for(i=0;*(point+i);i++)
        if(*(point+i)==ch)
			return i;
}


void get_relation(int (*a)[M],char *p)//输入序偶根据第一与第二元素在结点序列中的位置将关系矩阵相应元素置1
{
    int k1,k2;
    char ch1,ch2;
    printf("第二步:输入关系的各个序偶(输入<*,*>时结束):\n");
    while(1)
    {
        printf("<");
        ch1=getche();
        printf(",");
        ch2=getche();
        printf(">\n");
        if(ch1=='*')break;
        k1=get_position(ch1,p);//取得第一元素在p中的位置序号
        k2=get_position(ch2,p);
        a[k1][k2]=1;
    }
}


void output_relat_array(int (*a)[M],int arry_w)//输出关系矩阵
{
    int i,j;
    for(i=0;i<arry_w;i++)
    {
        for(j=0;j<arry_w;j++)
            printf("%4d",a[i][j]);
        printf("\n");
    }
}

void output_relate(int (*a)[M],int arry_w,char *p)//关系矩阵中如果有元素为1,则根据该序号去结点序列中查找其相应结点
{
    int i,j;
    int count=0;
    printf("{");
    for(i=0;i<arry_w;i++)
        for(j=0;j<arry_w;j++)
    	   if(a[i][j]==1){ printf("<%c,%c>,",*(p+i),*(p+j));count++;}
    printf("\b}");
    printf("\n");
}

void Eq_closure(int (*a)[M],int arry_w,char *p)//利用关系矩阵主对角线元素全赋值为1求自反闭包
{
    int i,j;
    int eq[M][M];
    for(i=0;i<arry_w;i++)
        for(j=0;j<arry_w;j++)
            eq[i][j]=a[i][j];
    for(i=0;i<arry_w;i++)
        eq[i][i]=1;
    system("cls");
    printf("\n自反闭包为:r(R)=");
    output_relate(eq,arry_w,p);
    printf("自反闭包的关系矩阵为:\n");
    output_relat_array(eq,arry_w);
}

void Sym_closure(int (*a)[M],int arry_w,char *p)//利用转置矩阵与原矩阵的逻辑和求对称闭包
{
    int i,j;
    int sym[M][M],sym2[M][M];
    for(i=0;i<arry_w;i++)
        for(j=0;j<arry_w;j++)
            sym[i][j]=a[i][j];
        for(i=0;i<arry_w;i++)
        for(j=0;j<arry_w;j++)
            sym2[i][j]=a[j][i];
        for(i=0;i<arry_w;i++)
        for(j=0;j<arry_w;j++)
            sym[i][j]|=sym2[i][j];
    system("cls");
    printf("\n对称闭包为:s(R)=");
    output_relate(sym,arry_w,p);
    printf("对称闭包的关系矩阵为:\n");
    output_relat_array(sym,arry_w);
}

void trs_closure(int (*a)[M],int arry_w,char *p)//warshall算法求传递闭包
{
    int i,j,k;
    int trs[M][M];
    for(i=0;i<arry_w;i++)
        for(j=0;j<arry_w;j++)
            trs[i][j]=a[i][j];
    for(k=0;k<arry_w;k++)
        for(i=0;i<arry_w;i++)
            if(trs[i][k]==1)
                for(j=0;j<arry_w;j++)
                    trs[i][j]=trs[i][j]||trs[k][j];
    system("cls");
    printf("\n传递闭包为:t(R)=");
    output_relate(trs,arry_w,p);
    printf("传递闭包的关系矩阵为:\n");
    output_relat_array(trs,arry_w);

}

main()
{
    int a[M][M]={0};
    char point[M];
    int slect,stlen;
    char *p;
    printf("\n\n\t该程序用于求解关系的各种闭包\n\n");
    p=get_element(point);//输入结点p取得其起始位置
    str_sort(p);//结点重新排序
    stlen=strlen(point);
    get_relation(a,p);//根据输入的关系的序偶构建关系矩阵a
    system("cls");

    while(1)
    {
        printf("\n\n\t\t请选择下列功能进行闭包的求解\n");
        printf("\t\t1、输出所输入的关系\n");
        printf("\t\t2、自反递闭包并输出\n");
        printf("\t\t3、求对称闭包并输出\n");
        printf("\t\t4、求传递闭包并输出\n");
        printf("\t\t0、退出程序\n\n");
    
		printf("\t\t请输入你的选项并回车(0,1,2,3,4)....\n");
		fflush(stdin);
		scanf("%d",&slect);
		while(slect*(slect-1)*(slect-2)*(slect-3)*(slect-4)!=0)
		{
			printf("\n\t\t请重新输入你的选项并回车(0,1,2,3)....\n");
			scanf("%d",&slect);
		}
		switch(slect)
		{
			case 1: 
				printf("\nR=");
				output_relate(a,stlen,p);
				printf("\n关系矩阵为:\n");
				output_relat_array(a,stlen);break;
			case 2: Eq_closure(a,stlen,p);break;
			case 3: Sym_closure(a,stlen,p);break;
			case 4: trs_closure(a,stlen,p);break;
			case 0: exit(0);
		}
		printf("\n按任意键继续.......");
		getch();
	}
}

运行结果是:


  • 10
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值