这是大二上离散数学的结课大作业。当时写这个作业比较困难,主要是因为网上没有类似的东西,最后是通过求助学长得到的解决方式(感谢学长)。
所以把自己的报告和代码(C/C++)放上来供大家参考。如有疏漏和错误,欢迎讨论纠正。
思路概述
输入群
输入群的阶数n。
输入群中所有元素之间相互运算的结果。
判断群是否为循环群
根据“素数阶群都是循环群”判断该群是否是循环群,即若n是素数,则该群为循环群,否则需要通过进一步判断确定该群是否是循环群。
若n不是素数,则寻找该群是否存在一个四阶子群与克莱因四元群同构。由于循环群的子群都是循环群,所以若存在满足上述条件的子群,该群为非循环群。
若同时满足n不是素数且该群不存在与克莱因四元群同构的子群,则通过枚举判断该群是否存在一个种子生成元。若存在,则该群是循环群,否则该群是非循环群。
求解所有子群
若该群为循环群,则利用定理10.14求解所有子群。若G=<a>是n阶循环群,则对n的每个正因子d,G恰好含有一个d 阶子群。
若该群为非循环群,则通过枚举遍历的方式求解所有子群。首先求解包含群中每一个元素和单位元的最小子群,然后将所有子群进行合并求出新子群,直至不再产生新的子群。此时所得到的子群就是该群的所有子群。
算法实现
全局变量
在算法实现过程中,我使用了一些全局变量。下面将对全局变量的含义作简单解释,以便对后续算法的理解。
int group[SIZE][SIZE]={0};
//group[][]二维数组用来存储群中所有元素的运算结果
//例:group[1][2]代表1*2的运算结果
int n=0;
//n代表群的阶数
int e=0;
//e代表群的单位元
int scy=0;
//若n阶群是循环群,则scy代表循环群的生成元
//若n阶群是非循环群,则该变量不被使用
int mg[SIZE][SIZE]={0};
//若n阶群是循环群,则该变量不被使用
//若n阶群是非循环群,则mg[a][b]代表非循环群在求解得到的所有子群中,
//第a个子群中的第b个元素
功能性函数
在算法实现过程中,有部分函数使用较为广泛,在正式使用算法求解问题之前,我先对这些函数作介绍,以便后续代码的理解。
判断一个元素是否存在于一个数组中
int in(int t,int mem[])
{
//判断t是否存在于mem数组中
//若t存在于mem[]数组中return 1
//否则return 0
for(int i=1;mem[i]!=0;i++)
{
if(t==mem[i])return 1;
}
return 0;
}
判断两个群是否相等
int g_equal(int a,int b)
{
//判断mg[a][]与mg[b][]两个有序数组代表的两个群是否相等
//若相等则return 1
//否则return 0
for(int i=1;;i++)
{
if(mg[a][i]==0&&mg[b][i]==0)return 1;
else
{
if(mg[a][i]!=mg[b][i])return 0;
}
}
}
主函数
主函数主要分为四部分:
输入群
找到群的单位元e
判断群是否为循环群
针对n阶群是循环群和不是循环群两种情况分别求解所有子群
int main()
{
input(); //输入群
find_e();//找到群的单位元e
int cycle=cycle_or_no();
//判断输入的n阶群是否是循环群,若是,则cycle=1,否则cycle=0
if(cycle==1)
{
//如果群是循环群
//根据定理10.14求所有子群
cycle_sub_group();
}
else//如果是非循环群
{
no_cycle_sub_group(); //求非循环群的子群
}
return 0;
}
输入群
首先输入群的阶数n。
为了表达以及计算方便,我们将群中n个元素分别用1,2,3...,n表示,并且设群的运算为*。
那么我们依次输入:
1*1,1*2,...,1*n,
2*1,2*2...,2*n,
...
n*1,n*2,...,n*n
的结果,即可完成群的输入。
void input()
{
//输入群
//首先输入阶数n
//然后输入群中所有元素的运算结果,并将结果存在group[][]数组中
scanf("%d",&n)
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&group[i][j]);
}
}
}
找到群的单位元e
遍历群中所有元素,寻找是否存在一个元素,能够使得其与其他元素运算得结果都与其他元素相等,即对群中任意元素x,若group[e][x]==x&&group[x][e]==x,则e为该群的单位元。
void find_e()
{
//找得群的单位元e
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n+1;j++)
{
if(j==n+1)
{
e=i;
return;
}
if(group[i][j]!=j||group[j][i]!=j)
{
break;
}
}
}
}
判断群是否为循环群
根据“素数阶群都是循环群”判断该群是否是循环群,即若n是素数,则该群为循环群,否则需要通过进一步判断确定该群是否是循环群。
int prime(int n)
{
//判断n是否是素数
//若是质数则return 1
//否则return 0
for(int i=2;i<=sqrt(n);i++)
{
if(n%i==0)return 0;
}
return 1;
}
若n不是素数,则寻找该群是否存在一个四阶子群与克莱因四元群同构。由于循环群的子群都是循环群,所以若存在满足上述条件的子群,该群为非循环群。
判断该群是否有与克莱因四元群同构的子群:
首先筛选出所有阶为2的元素。
若阶为2的元素小于三个则不存在,若大于等于三个则继续判断。
任选3个阶为2的元素,设3个元素分别为a,b,c,若存在一组a,b,c满足a*b=b*a=c且a*c=c*a=b且b*c=c*b=a,则该四阶群与克莱因四元群同构,即n阶群有与克莱因四元群同构的子群。
int same_with_klein()
{
//判断n阶群是否存在与克莱因四元群同构的子群
//若存在return 1
//否则return 0
//首先筛选出所有阶为2的元素
int grade_is_2[SIZE]={0},cnt=0;
for(int i=1;i<=n;i++)
{
if(group[i][i]==e&&i!=e)grade_is_2[++cnt]=i;
}
//构造克莱因群的同构;
if(cnt<3)return 0;
for(int i=1;i<=cnt;i++)
{
for(int j=i+1;j<=cnt&&j!=i;j++)
{
for(int k=j+1;k<=cnt&&k!=j&&k!=i;k++)
{
if(group[grade_is_2[i]][grade_is_2[j]]==grade_is_2[k]&&group[grade_is_2[j]][grade_is_2[i]]==grade_is_2[k]&&
group[grade_is_2[i]][grade_is_2[k]]==grade_is_2[j]&&group[grade_is_2[k]][grade_is_2[i]]==grade_is_2[j]&&
group[grade_is_2[j]][grade_is_2[k]]==grade_is_2[i]&&group[grade_is_2[k]][grade_is_2[j]]==grade_is_2[i])
return 1;
}
}
}
return 0;
}
若同时满足n不是素数且该群不存在与克莱因四元群同构的子群,则通过枚举判断该群是否存在一个种子生成元。若存在,则该群是循环群,否则该群是非循环群。
判断n阶群是否存在一个种子生成元:
枚举群中的所有元素,检验该元素是否为一个生成元;
将该元素作为生成元生成一个群,若生成的群中包含输入的n阶群中的所有元素,那么该元素是该n阶群的生成元。
如果所有元素都不是n阶群的生成元,则该n阶群没有种子生成元。
int is_scy(int x)
{
//判断x是否是n阶群的种子生成元
//若是return 1
//否则return 0
int exist[256]={0};
int t=x;
for(int i=1;i<=n;i++)
{
exist[group[t][x]]=1;
t=group[t][x];
}
for(int i=1;i<=n;i++)
{
if(exist[i]==0)return 0;
}
return 1;
}
判断群是否是循环群的整体算法
int cycle_or_no()
{
//判断n阶群是否是循环群
//若是循环群return 1
//否则return 0
if(prime(n)==1)return 1;//判断n是否为素数
if(same_with_klein()==1)return 0;
//判断是否有和克莱因四元群同构的子群
//穷举寻找生成元
for(int i=1;i<=n;i++)
{
if(is_scy(i)==1)
{
scy=i;
return 1;
}
}
return 0;
}
求解所有子群
若该群为循环群,则利用定理10.14求解所有子群。
首先找到n的所有正因数d。
寻找群中阶数为n/d的元素作为d阶子群的生成元。
将n/d阶元素作为生成元求得d阶子群。
void cycle_sub_group()
{
//找出所有的d阶子群
//根据定理10.14求所有子群
int cnt=0;
for(int i=1;i<=n;i++)
{
if(n%i==0)
find_d_sub_group(i,++cnt);
//求i阶子群,且该子群为求得的第cnt+1个子群
}
//输出一个只有单位元的子群
printf("子群中的元素有:{%d}\n",e);
}
void find_d_sub_group(int d,int num)
{
//求n/d阶生成元产生的第num个子群并输出
int mem[SIZE]={0};
int t;
int i,cnt=0;
for(i=1;i<=n;i++)
{
//寻找n/d阶生成元
if(i!=e)t=i;//此处不求只包含单位元的子群
else continue;
int j=0;
for(j=1;j<n/d;j++)
{
t=group[t][i];
if(j<n/d-1&&t==e)break;
//避免求n/d阶群时,n/d-k阶群也满足要求的情况
}
if(t==e&&j==n/d)break;
}
//此时i是n/d阶生成元
if(i>n)return ;//如果没找到符合要求的生成元,那么i>n
t=i;
mem[++cnt]=e;
while(in(t,mem)!=1)//用生成元生成子群
{
mem[++cnt]=t;
t=group[t][i];
}
//输出子群
printf("子群中的元素有:{");
for(int i=1;i<=cnt;i++)
{
printf("%d",mem[i]);
if(i!=cnt)printf(",");
}
printf("}\n");
}
若该群为非循环群,则通过枚举遍历的方式求解所有子群。
首先求解包含群中每一个元素和单位元的最小子群,在每次得到一个子群之后,都要和除它自己以外其他所有子群进行比较,若其与已有子群相同,那么进行去重,即删除该子群。
void find_every_min_group()
{
//寻找包含每个元素的最小的群
for(int i=1;i<=n;i++)
{
find_min_group(i);
}
}
void find_min_group(int i)
{
//寻找包含元素i的最小的群
int cnt=0;//cnt相当于一个指针,指示最后一个群的位置
int t=i;
mg[i][++cnt]=e;//首先把单位元放进去,因为每个子群里必定有单位元
//mg[i]表示包含元素i的最小子群,mg是min_group的简写
if(i==e)return;//如果这个元素是单位元则里面只有单位元直接返回
mg[i][++cnt]=i;
//一开始集合里只有这个元素本身和单位元
//接从前到后遍历这个集合
//每次把当前元素和它前面的所有元素(包含它自己)乘一遍,
//如果出现了新元素就添加到集合的后面
//遍历完就得到了一个最小的子群
int now=1;
for(;now<=cnt;now++)
{
for(int k=1;k<=now;k++)
{
if(in(group[mg[i][now]][mg[i][k]],mg[i])!=1)
{
mg[i][++cnt]=group[mg[i][now]][mg[i][k]];
}
if(in(group[mg[i][k]][mg[i][now]],mg[i])!=1)
{
mg[i][++cnt]=group[mg[i][k]][mg[i][now]];
}
}
}
sort(mg[i]+1,mg[i]+cnt+1);//排序以便判断群是否相等时的比较
}
2. 在求得所有的最小子群后,将所有子群进行合并求出新子群并将新子群进行去重处理,直至不再产生新的子群。此时所得到的子群就是该群的所有子群。
void col(int a,int b,int num)
{
//将mg[a][]和mg[b][]两个群合并到mg[num][]中
//首先把a、b中的所有元素提取出来
int ab[SIZE]={0};
int i=0;
for(i=1;mg[a][i]!=0;i++)
{
ab[i]=mg[a][i];
}
int j=1;
while(mg[b][j]!=0)
{
if(in(mg[b][j],ab)!=1)ab[i++]=mg[b][j];//元素的去重
j++;
}
sort(ab+1,ab+i);//排序以便比较两个群是否相等
for(int ii=1;ab[ii]!=0;ii++)
{
mg[num][ii]=ab[ii];//将数组ab[]复制到mg[num][]中
}
//下面这一段是把所有元素进行运算然后求出子群
i--;
int now=1;
for(;now<=i;now++)
{
for(int k=1;k<=now;k++)
{
if(i>=n)
//当子群中的元素数目已经大于等于n,那么代表该群不可扩展
{
sort(mg[num]+1,mg[num]+i+1);
return;
}
if(in(group[mg[num][now]][mg[num][k]],mg[num])!=1)
{
mg[num][++i]=group[mg[num][now]][mg[num][k]];
}
if(in(group[mg[num][k]][mg[num][now]],mg[num])!=1)
{
mg[num][++i]=group[mg[num][k]][mg[num][now]];
}
}
}
sort(mg[num]+1,mg[num]+i+1);
}
求非循环群的所有子群
void no_cycle_sub_group()
{
//求非循环群的所有子群
//先找包含每个元素的最小的群
find_every_min_group();
//对最小群去重
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(i==j)continue;
int xiangdeng=g_equal(i,j);
if(xiangdeng==1)
{
for(int k=1;mg[j][k]!=0;k++)
{
mg[j][k]=0;
}
}
}
}
//每次再选择两个群合并,
//新群如果没出现过就添加到群的集合
//最后就能得到所有子群
int sum=n;//合并群的总数
int same=0;
for(int i=1;i<=sum;i++)
{
for(int j=i+1;j<=sum;j++)
{
if(i!=j)
{
col(i,j,sum+1);
same=0;
for(int k=1;k<=sum;k++)
{
if(g_equal(k,sum+1)==1)//去重
{
same=1;
for(int ii=1;mg[sum+1][ii]!=0;ii++)
{
mg[sum+1][ii]=0;
}
break;
}
}
if(same==0)sum++;
}
}
}
//输出所有子群
int cnt=0;
for(int i=1;i<=sum;i++)
{
if(mg[i][1]==0)continue;
else print_sub_group_of_no_cycle(i,++cnt);
}
}
void print_sub_group_of_no_cycle(int x,int cnt)
{
//输出mg[x][]所代表的子群,且这个子群是求得的第cnt个子群
printf("第%d个子群中的元素有{",cnt);
for(int i=1;mg[x][i]!=0;i++)
{
printf("%d",mg[x][i]);
if(mg[x][i+1]!=0)
printf(",");
}
printf("}\n");
}
附:参考用例和运行结果截图




附:完整代码
#include <bits/stdc++.h>
using namespace std;
#define SIZE 1000
int group[SIZE][SIZE]={0};
int n=0;
int e=0;
int scy=0;
int mg[SIZE][SIZE]={0};//非循环群包含每个元素的最小的群
void input()
{
/*
输入群中的元素以及运算结果
首先输入阶数n
最后输入n*n个元素,表示运算的结果
*/
printf("输入元素的阶数n(n<=250):");
scanf("%d",&n);
printf("在这里我们分别将n个元素表示为:1,2,3,4,...,n,我们假设群的运算为*,");
printf("\n那么请你依次输入\n1*1,1*2,...,1*n,\n2*1,2*2...,2*n,\n...\nn*1,n*2,...,n*n\n的结果.\n");
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&group[i][j]);
}
}
}
int prime(int n)
{
//判断n是否是质数
for(int i=2;i<=sqrt(n);i++)
{
if(n%i==0)return 0;
}
return 1;
}
void find_e()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n+1;j++)
{
if(j==n+1)
{
e=i;
return;
}
///
//printf("%d\n",group[i][j]);
if(group[i][j]!=j||group[j][i]!=j)
{
break;
}
}
}
}
int same_with_klein()
{
//首先筛选出所有阶为2的元素
int grade_is_2[SIZE]={0},cnt=0;
for(int i=1;i<=n;i++)
{
if(group[i][i]==e&&i!=e)grade_is_2[++cnt]=i;
}
//构造克莱因群的同构;
if(cnt<3)return 0;
for(int i=1;i<=cnt;i++)
{
for(int j=i+1;j<=cnt&&j!=i;j++)
{
for(int k=j+1;k<=cnt&&k!=j&&k!=i;k++)
{
if(group[grade_is_2[i]][grade_is_2[j]]==grade_is_2[k]&&group[grade_is_2[j]][grade_is_2[i]]==grade_is_2[k]&&
group[grade_is_2[i]][grade_is_2[k]]==grade_is_2[j]&&group[grade_is_2[k]][grade_is_2[i]]==grade_is_2[j]&&
group[grade_is_2[j]][grade_is_2[k]]==grade_is_2[i]&&group[grade_is_2[k]][grade_is_2[j]]==grade_is_2[i])
return 1;
}
}
}
return 0;
}
int is_scy(int x)
{
int exist[256]={0};
int t=x;
for(int i=1;i<=n;i++)
{
exist[group[t][x]]=1;
t=group[t][x];
}
for(int i=1;i<=n;i++)
{
if(exist[i]==0)return 0;
}
return 1;
}
int cycle_or_no()
{
if(prime(n)==1)return 1;
if(same_with_klein()==1)return 0;//判断是否有和克莱因群同构的子群
//穷举寻找生成元
for(int i=1;i<=n;i++)
{
if(is_scy(i)==1)
{
scy=i;
return 1;
}
}
return 0;
}
int in(int t,int mem[])
{
//判断t在不在mem数组中
for(int i=1;mem[i]!=0;i++)
{
if(t==mem[i])return 1;
}
return 0;
}
void find_d_sub_group(int d,int num)
{
//求n/d阶生成元产生的子群
/*
定理10.14 设G=<a>是循环群.
(1) G的子群仍是循环群.
(3) 若G=<a>是n阶循环群,则对n的每个正因子d,
eG恰好含有一个d 阶子群.那么生成元的阶数是n/d.
*/
//根据以上定理求所有子群
int mem[SIZE]={0};
int t;
int i,cnt=0;
//printf("e=%d\n",e);
for(i=1;i<=n;i++)
{
//寻找n/d阶生成元
if(i!=e)t=i;
else continue;
int j=0;
for(j=1;j<n/d;j++)
{
t=group[t][i];
if(j<n/d-1&&t==e)break;
}
if(t==e&&j==n/d)break;//这个地方不对
}
//此时i就是那个生成元
if(i>n)return ;
t=i;
mem[++cnt]=e;
while(in(t,mem)!=1)
{
mem[++cnt]=t;
t=group[t][i];
}
printf("子群中的元素有:{");
for(int i=1;i<=cnt;i++)
{
printf("%d",mem[i]);
if(i!=cnt)printf(",");
}
printf("}\n");
}
void cycle_sub_group()
{
//找出所有的d阶子群
//如果群是循环群
/*
定理10.14 设G=<a>是循环群.
(1) G的子群仍是循环群.
(3) 若G=<a>是n阶循环群,则对n的每个正因子d,
eG恰好含有一个d 阶子群.那么生成元的阶数是n/d.
*/
//根据以上定理求所有子群
int cnt=0;
for(int i=1;i<=n;i++)
{
if(n%i==0)
find_d_sub_group(i,++cnt);
}
//输出一个只有单位元的子群
printf("子群中的元素有:{%d}\n",e);
}
void find_min_group(int i)
{
int cnt=0;
int t=i;
mg[i][++cnt]=e;
if(i==e)return;//如果这个元素是单位元则里面只有单位元直接返回
mg[i][++cnt]=i;
//一开始集合里只有这个元素本身和单位元
//接从前到后遍历这个集合
//每次把当前元素和它前面的所有元素(包含它自己)乘一遍,
//如果出现了新元素就添加到集合的后面
//遍历完就得到了一个最小的子群
int now=1;
for(;now<=cnt;now++)
{
for(int k=1;k<=now;k++)
{
// printf("此时包含%d的最小的群中的元素有:",i);
// for(int ii=1;mg[i][ii]!=0;ii++)printf("%d,",mg[i][ii]);
// printf("\n");
if(in(group[mg[i][now]][mg[i][k]],mg[i])!=1)
{
mg[i][++cnt]=group[mg[i][now]][mg[i][k]];
}
if(in(group[mg[i][k]][mg[i][now]],mg[i])!=1)
{
mg[i][++cnt]=group[mg[i][k]][mg[i][now]];
}
}
}
sort(mg[i]+1,mg[i]+cnt+1);
}
void find_every_min_group()
{
//寻找包含每个元素的最小的群
for(int i=1;i<=n;i++)
{
find_min_group(i);
}
}
int g_equal(int a,int b)
{
//判断两个群是否相等
// printf("判断第%d和第%d个群是否相等\n",a,b);
// for(int i=1;mg[a][i]!=0;i++)printf("%d,",mg[a][i]);
// printf("这些是第%d个群中的元素\n",a);
// for(int i=1;mg[b][i]!=0;i++)printf("%d,",mg[b][i]);
// printf("这些是第%d个群中的元素\n",b);
for(int i=1;;i++)
{
if(mg[a][i]==0&&mg[b][i]==0)return 1;
else
{
if(mg[a][i]!=mg[b][i])return 0;
}
}
}
void col(int a,int b,int num)
{
//将mg[a]和mg[b]两个群合并到mg[num]中
//首先把a、b中的所有元素提取出来
int ab[SIZE]={0};
int i=0;
// printf("第%d个子群的元素有:",a);
// for(int ii=1;mg[a][ii]!=0;ii++)printf("%d ",mg[a][ii]);
// printf("\n");
// printf("第%d个子群的元素有:",b);
// for(int ii=1;mg[b][ii]!=0;ii++)printf("%d ",mg[b][ii]);
// printf("\n");
for(i=1;mg[a][i]!=0;i++)
{
ab[i]=mg[a][i];
}
int j=1;
while(mg[b][j]!=0)
{
if(in(mg[b][j],ab)!=1)ab[i++]=mg[b][j];
j++;
}
sort(ab+1,ab+i);
for(int ii=1;ab[ii]!=0;ii++)
{
mg[num][ii]=ab[ii];
}
//下面这一段是把所有元素进行运算然后求出子群
i--;
int now=1;
for(;now<=i;now++)
{
for(int k=1;k<=now;k++)
{
// printf("此时第%d个群中的元素有:",num);
// for(int ii=1;mg[num][ii]!=0;ii++)printf("%d,",mg[num][ii]);
// printf("\n");
if(i>=n)
{
sort(mg[num]+1,mg[num]+i+1);
return;
}
if(in(group[mg[num][now]][mg[num][k]],mg[num])!=1)
{
mg[num][++i]=group[mg[num][now]][mg[num][k]];
}
if(in(group[mg[num][k]][mg[num][now]],mg[num])!=1)
{
mg[num][++i]=group[mg[num][k]][mg[num][now]];
}
}
}
sort(mg[num]+1,mg[num]+i+1);
// printf("此时第%d个群中的元素有:",num);
// for(int ii=1;mg[num][ii]!=0;ii++)printf("%d,",mg[num][ii]);
// printf("\n");
}
void print_sub_group_of_no_cycle(int x,int cnt)
{
printf("第%d个子群中的元素有{",cnt);
for(int i=1;mg[x][i]!=0;i++)
{
printf("%d",mg[x][i]);
if(mg[x][i+1]!=0)
printf(",");
}
printf("}\n");
}
void no_cycle_sub_group()
{
//非循环群的子群
//先找包含每个元素的最小的群
find_every_min_group();
//对最小群去重
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(i==j)continue;
int xiangdeng=g_equal(i,j);
// if(xiangdeng)printf("第%d个和第%d个群相等\n",i,j);
// else printf("第%d个和第%d个群不相等\n",i,j);
if(xiangdeng==1)
{
for(int k=1;mg[j][k]!=0;k++)
{
mg[j][k]=0;
}
}
}
}
//每次再选择两个群合并,
//新群如果没出现过就添加到群的集合
//最后就能得到所有子群
int sum=n;//合并群的总数
int same=0;
for(int i=1;i<=sum;i++)
{
for(int j=i+1;j<=sum;j++)
{
if(i!=j)
{
col(i,j,sum+1);
same=0;
for(int k=1;k<=sum;k++)
{
if(g_equal(k,sum+1)==1)//去重
{
same=1;
for(int ii=1;mg[sum+1][ii]!=0;ii++)
{
mg[sum+1][ii]=0;
}
break;
}
}
if(same==0)sum++;
}
}
}
//输出所有子群
int cnt=0;
for(int i=1;i<=sum;i++)
{
if(mg[i][1]==0)continue;
else print_sub_group_of_no_cycle(i,++cnt);
}
}
int main()
{
input();
find_e();//找到群的单位元
int cycle=cycle_or_no();
printf("该群的单位元为:%d\n",e);
if(cycle==1)
{
//如果群是循环群
/*
定理10.14 设G=<a>是循环群.
(1) G的子群仍是循环群.
(3) 若G=<a>是n阶循环群,则对n的每个正因子d,G恰好含有一个d 阶子群.那么生成元的阶数是n/d.
*/
//根据以上定理求所有子群
cycle_sub_group();
}
else//如果是非循环群
{
no_cycle_sub_group();
}
return 0;
}