[关闭]
@chawuciren 2019-10-21T15:26:46.000000Z 字数 1789 阅读 467

CINTA作业12--编程题(子群)

CINTA
1、构造Zp*的子群。随机取一个Zp*中的元素g,不断做g的平方、g的立方,g的4次方,......,把所得放到一个集合S中,直到S不再增加。并计算S的阶。

  1. /*
  2. * Input: 素数p
  3. * Output: Zp*的子集S的阶
  4. */
  5. int subgroup_1(int p){
  6. int* arr=(int *)malloc(sizeof(int)*p);//用一个空数组检查元素是否在子集中,存在将数组对应下标的元素置为1
  7. for(int i=0;i<p;i++) arr[i]=0;//初始化
  8. srand((unsigned)time(NULL));
  9. int a = rand() % (p-1)+1;//在1到p-1中随机取一个数
  10. int b=a;
  11. int count=0;
  12. while(1){
  13. b=b*a%p;//不断做g^2 g^3......
  14. if(arr[b]) break;//直到跑回原来的位置停止
  15. else arr[b]=1;//如果元素不存在则将元素放入子集中
  16. }
  17. for(int i=0;i<p;i++){
  18. if(arr[b]==1) count++;//计算子集中的元素个数
  19. }
  20. return count;
  21. }

2、构造Zp*的子群。对Zp*中的所有元素g做平方,所得放集合S中。计算S的阶。

  1. /*
  2. * Input: 素数p
  3. * Output: Zp*的子集S的阶
  4. */
  5. int subgroup_2(int p){
  6. int* arr=(int *)malloc(sizeof(int)*p);
  7. for(int i=0;i<p;i++) arr[i]=0;
  8. int b=0;
  9. int count=0;
  10. for(int i=1;i<p;i++){
  11. b=i*i%p;//对Zp*中的所有元素做平方
  12. arr[b]=1;//将所得放入S中
  13. }
  14. for(int i=0;i<p;i++){
  15. if(arr[b]==1) count++;
  16. }
  17. return count;
  18. }

3、构造Zn*的子群。取Zn*中的两个元素,放到集合S中,不断重复对S中的任意两个元素进行乘法,所得如果在S中则忽略,否则加入S,直到S不再增加。计算S的阶。

  1. /*
  2. * Input: 合数n
  3. * Output: Zn*的子集S的阶
  4. */
  5. int Subgroup(int n){
  6. int num=Euler_phi(n);//计算Zn*中有多少个元素
  7. int j=0;
  8. int*S=(int*)malloc(sizeof(int)*num);
  9. for(int i=1;i<n;i++){//算出所有Zn*的元素放入S中
  10. if(gcd(i,n)==1){
  11. S[j]=i;
  12. j++;
  13. }
  14. }
  15. int order=Calculation(S,num,n);//计算子群的阶
  16. return order;
  17. }
  18. int Calculation(int* S,int num,int n){
  19. int count=2;
  20. int p1=0;
  21. int p2=0;
  22. int stop=0;
  23. srand((unsigned)time(NULL));
  24. p1 = rand() % (num);
  25. do{
  26. p2=rand() % (num);
  27. }while(p2==p1);//随机取Zn*中的两个不同元素
  28. int* sub=(int*)malloc(sizeof(int)*num);//用于存放子群的元素
  29. int* inspect=(int*)malloc(sizeof(int)*n);//用于检查子群元素是否存在
  30. for(int i=0;i<num;i++){//初始化
  31. sub[i]=0;
  32. }
  33. for(int i=0;i<n;i++){//初始化
  34. inspect[i]=0;
  35. }
  36. sub[0]=S[p1];//选取的两个元素放入子集中
  37. sub[1]=S[p2];
  38. inspect[sub[0]]=1;//如果该元素已存在,将inspect数组对应下标的元素置1
  39. inspect[sub[1]]=1;
  40. for(int i=1;i<num;i++){
  41. for(int j=0;j<num;j++){
  42. if(i==j) {//如果没有新元素,循环停止
  43. stop=1;
  44. break;
  45. }
  46. if(inspect[sub[j]*sub[i]%n]==0){//如果是新元素,将新元素放入子集
  47. sub[count]=sub[j]*sub[i]%n;
  48. inspect[sub[j]*sub[i]%n]=1;
  49. count++;//计算阶
  50. }
  51. }
  52. if(stop==1) break;
  53. }
  54. return count;
  55. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注