辗除法求最大公约数和最小公倍数

时间:2021-10-03 00:36:15

        最近两天因为忙于工作的事,学习进展较慢。

        今天看了一个辗除法求最大公约数的例子,上网查了一下其数学原理,算是理解了这个算法的数学依据。

        对于两个正整数num1,num2,且num1>num2,如果num1除以num2余数为resd,若resd=0则num2即是两数的最大公约数,若resd≠0,则令num1=num2,num2=resd,再重复进行以上过程,直到resd=0,则此时num2的值即是所求两数的最大公约数。

证明过程如下:

     用gcd表示两数的最大公约数,如a=gcd(m,n)表示m和n的最大公约数是a。

     num1>num2,若num1=a*num2+b,则只需要证明gcd(num1,num2)=gcd(num2,b)即可。

     设m=gcd(num1,num2), n=gcd(num2,b),则m可被num1和num2整除,则m可被a*num2整除,可推知m可被num1-a*num2整除,而b=num1-a*num2,则m可被b整除,所以m是num2和b的公约数(不一定是最大公约数),则m≤n;同理可证:n是num1和num2的公约数,n≤m;由于m≤n和n≤m同时成立,所以m=n。

参考有关资料上的编程实例,编写的C语言程序如下:

#include<stdio.h>
int main()
{
   int num1, num2, a, b, temp;
   printf("Please input two numbers:\n");
   scanf("%d,%d", &num1, &num2);  //输入两个正整数
   if(num1 < num2)          //保证num1>num2,因为下面是用num1作被除数,num2作除数
    {
       temp = num1;
       num1 = num2;
       num2 = temp;
    }
   a =num1;
   b =num2;
   while(b != 0)  //辗转相除,直到余数为0
    {
       temp = a % b;
       a = b;
       b = temp;
    }
   printf("GCD:%d\n", a);
   printf("LCM:%d\n", num1 * num2 / a); //求最小公倍数,两个数的乘积等于它们最大公约数与最小公倍数的积
   return 0;
}


        今天在编译运行的时候出了点差错,输入两个数后得到的结果不正确,得到的是比较奇怪的数,我就把两个正整数不用输入改为自己赋初值,此时得到的结果正确,由此可见应该是输入的时候出错了。经过检查发现scanf("%d,%d",&num1, &num2); 这句输入程序中两个%d之间有逗号,而我从键盘输入时没有输这个逗号,导致了出错,要么把逗号去除,要么输数的时候两数之间加个逗号就正确了。这个错误可以给初学编程的人作为参考,避免犯类似的低级错误。