最近两天因为忙于工作的事,学习进展较慢。
今天看了一个辗除法求最大公约数的例子,上网查了一下其数学原理,算是理解了这个算法的数学依据。
对于两个正整数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之间有逗号,而我从键盘输入时没有输这个逗号,导致了出错,要么把逗号去除,要么输数的时候两数之间加个逗号就正确了。这个错误可以给初学编程的人作为参考,避免犯类似的低级错误。