一、 实验目的和要求
内容:
编程实现整除关系这一偏序关系上所有盖住关系的求取,并判定对应偏序集是否为格。
要求:
对任意给定正整数,利用整除关系求所有由其因子构成的集合所构成的格,判断其是否为格、有界格、有补格。并输出所有元素各自的补元素。
程序要求输入任意整数,输出它所有的因子,所有的整除关系,所有的盖住关系,判断对应的偏序集是不是一个格,是不是一个有界格,如果是有界格,是不是一个有补格,如果是有补格,输出所有元素的补元素,如果不是有补格,输出没有补元素的元素,以及有补元素的元素的补元素。
#include <iostream>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int n; //保存输入的整数n
vector<int> a; //保存n的所以因子
struct note //表示序偶的结构体
{
int x,y;
note(int aa,int bb)
{
x=aa;
y=bb;
}
};
vector<note> zhenchu; //保存所有整除关系的序偶
vector<note> COV; //保存所有盖住关系的序偶
vector<int> HasNoBu; //保存没有补元素的元素
vector<int> Bu[10000]; //保存有补元素的元素的补元素
void Prime() //计算出n的因子
{
for(int i=1;i<=n;i++)
{
if(n%i==0)
{
a.push_back(i);
}
}
}
void Divided() //计算出整除关系 并保存在zhenchu数组
{
for(int i=0;i<a.size();i++)
{
for(int j=i;j<a.size();j++)
{
if(a[j]%a[i]==0)
{
note tmp(a[i],a[j]);
zhenchu.push_back(tmp);
}
}
}
}
void SolveCOV() //计算出所有盖住关系,并保存在COV数组
{
for(int i=0;i<a.size()-1;i++)
{
for(int j=i+1;j<a.size();j++)
{
if(a[j]%a[i]==0)
{
int flag=0;
for(int k=i+1;k<j;k++)
{
if(a[k]%a[i]==0&&a[j]%a[k]==0)
{
flag=1;
break;
}
}
if(flag==0)
{
note tmp(a[i],a[j]);
COV.push_back(tmp);
}
}
}
}
}
int gcd(int x,int y) //计算最小公倍数
{
int r=1;
while(r)
{
r=y%x;
y=x;
x=r;
}
return y;
}
bool JudgeGe() //判断是不是格
{
for(int i=0;i<a.size();i++)
{
for(int j=i+1;j<a.size();j++)
{
int index=find(a.begin(),a.end(),gcd(a[i],a[j]))-a.begin();
if(index==a.size())
{
return false;
}
index=find(a.begin(),a.end(),a[i]*a[j]/gcd(a[i],a[j]))-a.begin();
if(index==a.size())
{
return false;
}
}
}
return true;
}
int G[10010][10010]; //判断是不是有界格用到的图
int flag; //深度优先搜索过程中,如果找到某个元素不比最大元素小,则flag标志成1
void DFS(int cur)
{
if(flag) return;
int tmp=0;
for(int i=cur+1;i<=n;i++)
{
if(G[cur][i]==1)
{
tmp=1;
break;
}
}
if(tmp==0&&cur!=n) //找到不是有界格的条件
{
flag=1;
return ;
}
for(int i=cur+1;i<=n;i++)
{
if(G[cur][i]==1)
{
DFS(i);
}
}
}
bool JudgeYouJieGe() //判断有界格,用有向图的深度优先遍历来判断是不是有界格
{
flag=0;
memset(G,0,sizeof(G));
for(int i=0;i<COV.size();i++)
{
G[COV[i].x][COV[i].y]=1;
}
DFS(1);
if(flag==0)
{
return true;
}
else
{
return false;
}
}
bool JudgeYouBuGe() //判断是不是有补格
{
int judge=0;
for(int i=0;i<a.size();i++)
{
int tmp=0;
for(int j=0;j<a.size();j++)
{
if(gcd(a[i],a[j])==1 && a[i]*a[j]/gcd(a[i],a[j])==n)
{
tmp=1;
Bu[i].push_back(a[j]);
}
}
if(tmp==0)
{
judge=1;
HasNoBu.push_back(a[i]);
}
}
if(judge==1)
{
return false;
}
else
{
return true;
}
}
int main()
{
printf("请输入整数n:");
scanf("%d",&n);
Prime();
printf("\n%d的所有因子为:\n",n);
for(int i=0;i<a.size();i++)
{
printf("%d ",a[i]);
}
Divided();
printf("\n\n所有的整除关系为:\n{");
for(int i=0;i<zhenchu.size();i++)
{
if(i==0) printf("<%d,%d>",zhenchu[i].x,zhenchu[i].y);
else printf(",<%d,%d>",zhenchu[i].x,zhenchu[i].y);
}
printf("}\n\n");
SolveCOV();
printf("所有的盖住关系为:\nCOV A={");
for(int i=0;i<COV.size();i++)
{
if(i==0) printf("<%d,%d>",COV[i].x,COV[i].y);
else printf(",<%d,%d>",COV[i].x,COV[i].y);
}
printf("}\n\n");
if(JudgeGe()==true)
{
printf("经过判断,这个偏序集是一个格\n\n");
}
else
{
printf("经过判断,这个偏序集不是一个格\n\n");
}
bool youjiege=JudgeYouJieGe();
if(youjiege==true)
{
printf("经过判断,这个偏序集是一个有界格\n\n");
}
else
{
printf("经过判断,这个偏序集不是一个有界格\n\n");
}
if(youjiege==true)
{
if(JudgeYouBuGe()==true)
{
printf("经过判断,这个偏序集是一个有补格\n各个元素的补元素分别是:\n");
for(int i=0;i<a.size();i++)
{
printf("%d 的补元素是:",a[i]);
for(int j=0;j<Bu[i].size();j++)
{
printf("%d ",Bu[i][j]);
}
printf("\n");
}
}
else
{
printf("经过判断,这个偏序集不是一个有补格\n\n没有补元素的元素是:");
for(int i=0;i<HasNoBu.size();i++)
{
printf("%d ",HasNoBu[i]);
}
printf("\n\n");
printf("其余元素都有补元素,各自的补元素分别是:\n");
for(int i=0;i<a.size();i++)
{
if(Bu[i].size()!=0)
{
printf("%d 的补元素是:",a[i]);
for(int j=0;j<Bu[i].size();j++)
{
printf("%d ",Bu[i][j]);
}
printf("\n");
}
}
}
}
return 0;
}