算法导论-数论里边的一些算法

看了数论一章 , 做了些习题 , 这些代码对于解一些习题有帮助。

//交换a,b

void mswap(int &a,int &b){
 a = a^b;
 b=a^b;
 a = a^b;
}
//最大公约数
int gcd(int a,int b){
 if(a<b) mswap(a,b);
 int t = 0;
 while(b!=0){
  t = a;
  a = b;
  b = t%b;
 }
 return a;
}

//最大公约数,n个数
int gcd(int ar[],int n){
 if(n==2) return gcd(ar[0],ar[1]);
 else return gcd(ar[0],gcd(ar+1,n-1));
}

//三元组(d,x,y)
typedef struct triple{
 int d;
 int x;
 int y;
 void mprint(){
  cout<<"(d,x,y) = ("<<d<<","<<x<<","<<y<<")"<<endl;
 }
};

//扩展的最大公约数算法 , 求d = ax+by,以后有用;
triple extended_gcd(int a,int b){
 if(b==0){
  triple t1;
  t1.d = a;
  t1.x = 1;
  t1.y = 0;
  return t1;
 }
 else {
  triple t2 = extended_gcd(b,a%b);
  triple t;
  t.d = t2.d;
  t.x = t2.y;
  t.y = t2.x - t2.y * (a/b);
  return t;
 }
}
//最小公倍数
int lcm(int a,int b){
 return a*b/gcd(a,b);
}
//最小公倍数,n个数
int lcm(int ar[],int n){
 if(n==2) return ar[0]*ar[1]/gcd(ar[0],ar[1]);
 else{
  int t = lcm(ar+1,n-1);
  return ar[0]*t/gcd(ar[0],t);
 }
}
int mod(int a,int b){求模,当a是负数,要+b处理
 if(a < 0) return a%b+b;
 else return a%b;
}

//modular_liner_equation_solver ,解:模n的线性方程-->ax=b(mod n)
void mod_line_equ(int a,int b,int n){
 triple t = extended_gcd(a,n);
 //t.mprint();
 if(b%t.d == 0){
  int x0 = mod((t.x*(b/t.d)), n);//(t.x*(b/t.d)) mod n 
  int x=x0;
  cout<<x0<<endl;
  for(int i = 0 ; i < t.d ;i++){
   x = (x0 + i*(n/t.d))%n ;
   cout<<"("<<x<<"*"<<a<<"%"<<n<<") = "<<(x*a)%n<<endl;
  }
 }
 else cout<<"no solution";
 
}
int mod_exp(int a,unsigned int b ,int n){//求解a^b % n
 int d = 1,bt = (1<<30) ,bi = 0;
 for(int i = 0 ; i < 31 ; i++){
  d = d*d % n;
  bi = bt & b;
  bt = bt >> 1;
  if(bi > 0)
   d = d*a % n;
  // cout<<"d = "<<d<<endl;
 }
 return d;
 
}

void z_mul(int n){//生成Z(n,*)的集合 ,并且由最小的root,设为g,生成所有的元素
 int count = 0;
 int phi = Eular_phi_func(n);
 cout<<"phi("<<n<<") = " <<phi<<endl;
 int* a = new int[phi];
 memset(a,0,n);
 //生成集合中的元素
 a[count++] = 1;
 cout<<"Z("<<n<<",*)=(1,";
 for(int i = 2 ; i < n ; i++){
  if(gcd(n,i) == 1) {
   cout<<i<<",";
   a[count++] = i;
  }
 }
 cout<<")"<<endl;
 int least_g = 2;
 //找到最小的root g,为2,4,p^e,2*p^e,其中p在集合中,且为质数,e为任意整数
 for(i = 1 ; i < count ; i++)
  if(isPrime(a[i]) || a[i] == 4){
   least_g = a[i];
   break;
  }
 //由g生成集合中的所有元素
 for(i = 0 ; i < phi ; i++){
  cout<<least_g<<"^"<<i<<" mod "<<n<<" = " <<mod_exp(least_g,i,n)<<endl;
  }
}

bool isPrime(int a){//判断质数
 int n = (int)sqrt(a);
 if(a == 2) return true;
 for(int i = 2 ; i <= n ; i++ ){
  if(a%i == 0) return false;
 }
 return true;
}

int Eular_phi_func(int n){ //Eular phi function
int result = n;
for(int i = 2 ; i <= n ;i++)
 if(isPrime(i) && n%i==0 )
  result*=(1-1.0/i);
return result;

你可能感兴趣的:(算法导论-数论里边的一些算法)