離散數學實驗之求解關係的閉包運算
阿新 • • 發佈:2019-02-15
我自己寫不這麼好,說實在的,我也寫不出來。這是老師給我們的一個程式碼。我把他在這上面儲存下來,以後可能能用的到。
關係閉包運算
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();
}
}
執行結果是: