多个数的最大公约数和最小公倍数c++

最大公约数

个人思路

1.将数组元素进行排序,此处采用冒泡排序
2.利用辗转相除法:i>0时,a[i]和a[0]求最大公约数并且存入a[0] 
3.输出a[0]

n个数的最大公约数代码
方法一:辗转相除法

//**最大公约数:辗转相除法**
int greatest_common_divisor1(int a[],int n){
  int rem,i,temp;
  if(n==1) return a[0];
  if(n>1) {
   for(i=1;i<n;i++){
    temp = a[0];
    //辗转相除法 
     do{
       rem = a[i]%temp;
       a[i] = temp;
       temp = rem;
   }
   while(rem);
   a[0] = a[i];//不断更新a[0]的取值
   }
  //for(i=0;i<n;i++){ 
 // cout<< "a["<<i<<"]:"<<a[i]<<endl;} 
   return a[0];//返回最大公约数
  }
}

方法二:更相减损术

//**最大公约数:更相减损术**
int greatest_common_divisor2(int a[],int n){

  int dif,temp,i;
  if(n==1) return a[0];
  else{
  for(i=1;i<n;i++){
  temp = a[0];
  while(a[i]!=temp) 
  {
   dif = a[i]-temp;
   if(temp>dif){
    a[i] = temp;
    temp = dif;
   }
 else{
  a[i] = dif;
 }
  }
  a[0] = a[i];
  }
   //for(i=0;i<n;i++){ 
  // cout<< "a["<<i<<"]:"<<a[i]<<endl;} 
  return a[0];//返回最大公约数
  }
}
  

测试
只放了辗转相除法,更相减损术也进行了基本验证

#include<iostream>
using namespace std;
//**冒泡排序**
void bubble_sort(int a[],int n){ 
 bool flag=false;
 for(int i=0;i<n-1 && !flag;i++)
 {   int temp1;
  flag = true;
  for(int j=1;j<n-i;j++){
   if(a[j-1]>a[j]){
    temp1 = a[j];
    a[j] = a[j-1];
    a[j-1]=temp1;
    flag = false;
   }
  }
 }
}
int main()
{  
  int n;
  cout<<"输入个数n,其后是n个需要求取的自然数!"<<endl; 
 while(cin>>n && n) {
 // int te1,te2;
  int* seq = new int[n];
  for(int i=0;i<n;i++) {
   cin>>seq[i];
  } 
  bubble_sort(seq,n);
  cout<<"最大公约数:"<< greatest_common_divisor1(seq,n)<<endl;
  delete[] seq;
  }
   return 0;
}

测试结果
输入的第一个数为数据个数,其后为需要求取的自然数。

输入个数n,其后是n个需要求取的自然数!
3 12 36 96
最大公约数:12
4 24 36 98 24
最大公约数:2
4 13 14 15 41
最大公约数:1
4 55 55 55 55
最大公约数:55
4 7 7 4 4
最大公约数:1

最小公倍数

个人思路

1.利用两个数的最大公约数
2.公式:两数的最小公倍数=两数之积 除以 最大公约数
3.利用辗转相除法:a[1]和a[0]求最小公倍数存入a[1],a[2]和a[1]求最小公倍数存入a[2],
a[3]和a[2]求最小公倍数存入a[3]……
4.最终,a[n-1]就是n个数的最小公倍数

注意:

 a[i] = a[i]*(A/a[i-1]);这条语句本来应该是 a[i] = (a[i]*A)/a[i-1];
 先算乘法再算除法,但是这样容易溢出,所以可以先算除法,当然也可以用long long的类型。

n个数的最小公倍数代码

int least_common_multiple(int a[],int n) {
  int rem,i,A,temp;
  if(n==1) return a[0];
  if(n>1) {
   for(i=1;i<n;i++){
    A = a[i-1];//记录a[i-1]原始的数值
    temp = a[i];
    //辗转相除法 
     do{
       rem = a[i-1]%temp;
       a[i-1] = temp;
       temp = rem;
   }
   while(rem);
   //此时a[i-1]更新为a[i]和a[i-1]的最大公约数
   //a[i]=(a[i]*A)/a[i-1];//容易溢出
   a[i] = a[i]*(A/a[i-1]);//将两数的最小公倍数存入a[i]中
   }
 //for(i=0;i<n;i++){ 
 //cout<< "a["<<i<<"]:"<<a[i]<<endl;} 
   return a[n-1];//返回最小公倍数
  }
}

测试

int main()
{  
  int n;
  cout<<"输入个数n,其后是n个需要求取的自然数!"<<endl; 
 while(cin>>n ) {
  int* seq = new int[n];
  for(int i=0;i<n;i++) {
   cin>>seq[i];
  } 
 // bubble_sort(seq,n);//可以不用排序
  cout<<least_common_multiple(seq,n)<<endl;
   //cout<<"int最大值:"<<INT_MAX; 
  delete[] seq;
  }
 
   return 0;
}

测试结果

输入的第一个数为数据个数n,其后为需要求取的自然数。
输入个数n,其后是n个需要求取的自然数!
3 12 6 8
24
4 7832 534 15842 2492
14638008
4 1 2 3 4
12

纯粹为了记录,如果复制,记得说明来源,正确引用

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值