码迷,mamicode.com
首页 > 其他好文 > 详细

多个数的最大公约数

时间:2015-11-24 22:04:42      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:

---恢复内容开始---

最近在看一本算法的书。讲的都是一些基本的问题,并没有涉及很复杂的算法,或者说这本书更看重技巧。

其中开篇就讲了最大公约数的算法,觉得有可取之处,和大家分享一下。

提到最大公约数我们最先想到的一定是辗转相除法。

没错,永远不要蔑视我们的祖先,他们的智慧是无穷的。(扯远了,嘿嘿)

我们都在用辗转相除法来求最大公约数,却很少去想为什么辗转相除法就能求最大公约数呢?或者说怎么证明算法的正确性呢(至少我之前完全没有想过)。

这里我们感性的认识一下辗转相除法(不是很严格地证明一下)。

假设两个数a,b且a>b。 设a除以b商k,余数为r,那么会有a=k*b+r,那么b和r的最大公约数,就是a和b的最大公约数。所以问题就转换求成除数和余数的最大公约数,依次递归,递归的出口就是一个已知的条件:如果a能够被b整除,那么b就是a和b的最大公约数,所以辗转相除法递归代码如下:

int GCD1(int num1,int num2)
{
   if(num1%num2==0)
   {
    return num2;
   }
   else
   {
    int next1=num2;
    int next2=num1%num2;
    return GCD1(next1,next2);
    }
}

还有一种我们耳熟能详的求最大公约数的算法就是更相减损术,他的基本思想就是:两个数a,b且a>b,那么令c=a-b,然后把 b和c看成新的a和b,递归下去,递归出口就是一个已知的条件:如果a=b,那么a和b的最大公约数就是a或b。其实更相减损术和辗转相除法是一个东东,更相减损术就是让辗转相除法中的商(k)恒为1,所以大多数情况下,辗转相除法的效率要比更相减损术的效率高。给出更相减损术的代码:

int GCD2(int num1,int num2)
{
   if(num1==num2)
   {
      return num2;
   }
   else
  {
      int next1=  (num1>num2)? (num1-num2):(num2-num1);
      int next2= (num1>num2)?num2:num1;
      if(next1>next2)
      {
       return GCD2(next1,next2);
      }
      else
      {
         return GCD2(next2,next1);
      }
    }
}

 

好了,步入这次的正题:多个数求最大公约数(实际上就是辗转相除法的扩展)给出算法:

设一组数a1,a2,a3,a4,a5..

(1)对这一组数进行排序(从大到小)

(2)对每两个相邻的两个数进行如下操作:

    设相邻的两个数为A和B(A在前,因为已经排序,所以A>B),如果A=n*B(n为整数),也就是A能够被B整除,那么就令A=B;如果A不能被B整除则令A=A%B。

(3)重复(1)、(2)知道数组中每个数都相等,则最大公约数就为这个数。

 

给出完整程序:

#include<iostream>
using namespace std;
void Sort(int* num,int n);
int GCD3(const int* num,int n);
int main()
{

   int num[4]={756,504,630,2226};
   int result=GCD3(num,4);
   cout<<"数组:";
   for(int i=0;i<4;i++)
   {
      cout<<num[i]<<"  ";
   }
   cout<<"的最大公约数为:"<<result<<endl;
   return 0;
}

int GCD3(const int* num,int n)
{
   int *temp=new int[n];
   for(int i=0;i<n;i++)
   {
      temp[i]=num[i];
   }
   do
   { 
      if(temp[0]==temp[n-1])
      {
         break;
      }
      else
      {
         Sort(temp,n);//排序
         for(int i=0;i<n-1;i++)
         {
            if(temp[i]%temp[i+1]==0)
            {
               temp[i]=temp[i+1];
            }
            else
            {
               temp[i]=temp[i]%temp[i+1];
            }
         }
      }
   }while(temp[0]!=temp[n-1]);
   return temp[0];
}

//排序
void Sort(int* num,int n)
{

  //冒泡排序法
   for(int i=0;i<n-1;i++)
   {
      for(int j=i;j<n-1;j++)
      {
         if(num[i]<num[j+1])
         {
            int temp=num[i];
            num[i]=num[j+1];
            num[j+1]=temp;
         }
      }
    }
}

 

 

---恢复内容结束---

多个数的最大公约数

标签:

原文地址:http://www.cnblogs.com/qingergege/p/4992990.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!