算法——最大公約數


百度百科上介紹的最大公約數的求法(限兩個數)主要有兩種:輾轉相除法和更相減損法。

輾轉相除法

輾轉相除法,百度百科上的示例:

用(a,b)表示a和b的最大公約數。

例如,求(319,377):
∵ 319÷377=0(余319)
∴(319,377)=(377,319);
∵ 377÷319=1(余58)
∴(377,319)=(319,58);
∵ 319÷58=5(余29),
∴ (319,58)=(58,29);
∵ 58÷29=2(余0),
∴ (58,29)= 29;
∴ (319,377)=29.
也就是說,求兩個數的最大公約數時,先用較大數除以較小數,如果能整除,最大公約數就等於較小數;否則用較小數除以第一步的余數,如果能整除,最大公約數就等於第一步的余數;否則,用當前獲得的余數除以上一步的余數,直到能整除為止。此時作為除數的那個數就是最開始那兩個數的最大公約數。
下面是代碼:
 1 function gcm(m,n) {
 2    var a, c, e, f;
 3    //對m,n排序,較小的在前,較大的在后
 4    if(m > n) {
 5       a = m;
 6       m = n;
 7       n = a;
 8    }
 9    c = m, e = n, f = c;
10    while(c !== 0) {
11       f = e % c;
12       e = c;
13       c = f;
14    }
15    alert(e);
16    return e;
17 }

代碼中主要是while循環那里有點繞。(參考知乎上的答案

更相減損法

百度百科上的解釋:

第一步:任意給定兩個正整數;判斷它們是否都是偶數。若是,則用2約簡;若不是則執行第二步。
第二步:以較大的數減較小的數,接着把所得的差與較小的數比較,並以大數減小數。繼續這個操作,直到所得的減數和差相等為止。
用第一步中約掉的若干個2與第二步中等數的乘積就是所求的最大公約數。
 
例1、用更相減損術求98與63的最大公約數。
解:由於63不是偶數,把98和63以大數減小數,並輾轉相減:
98-63=35
63-35=28
35-28=7
28-7=21
21-7=14
14-7=7
所以,98和63的最大公約數等於7。
 
例2、用更相減損術求260和104的最大公約數。
解:由於260和104均為偶數,首先用2約簡得到130和52,再用2約簡得到65和26。
此時65是奇數而26不是奇數,故把65和26輾轉相減:
65-26=39
39-26=13
26-13=13
所以,260與104的最大公約數等於13乘以第一步中約掉的兩個2,即13*2*2=52。
 
下面是代碼:
 1 function gcm2(m,n) {
 2    var a, c, e, f, index = 0;
 3    //對m,n排序,較小的在前,較大的在后
 4    if(m > n) {
 5       a = m;
 6       m = n;
 7       n = a;
 8    }
 9    //如果m,n都為偶數
10    while(m % 2 === 0 && n % 2 === 0) {
11       m = m/2;
12       n = n/2;
13       index++;
14    }
15 
16    f = m, e = n, c = n - m;
17    while(c !== f) {
18       e = f;
19       f = c;
20       c = e - f;
21       if(c < 0) {
22          c = -c;
23       }
24    }
25    alert(f*2*index);
26    return f*2*index;
27 }

計算上輾轉相除法以除法為主,更相減損法以減法為主。計算次數上輾轉相除法計算次數相對較少,特別當兩個數字大小區別較大時計算次數的區別較明顯。

要求多個數的最大公約數,可以先求出其中任意兩個數的最大公約數,再求這個最大公約數與第三個數的最大公約數,依次求下去,直到最后一個數為止。最后所得的那個最大公約數,就是所有這些數的最大公約數。

求多個數的最小公倍數

兩個數的最小公倍數等於這兩個數的乘積除以這兩個數的最大公約數。

求多個數的最小公倍數時,可以先求出其中兩個數的最小公倍數,再求這兩個數的最小公倍數與第三個數的最小公倍數,以此類推,直到最后一個數為止。最后得到的最小公倍數就是這幾個數的最小公倍數。

下面是代碼:

 1 function smallestCommons(arr) {
 2   arr = arr.sort(function(a,b) {
 3     return a-b;
 4   });
 5   var brr = [];
 6   for (var i = arr[0]; i <= arr[1]; i++) {
 7      brr.push(i);
 8   }
 9   var m,n,c,e,f;
10   
11   for (var i = 0; i < brr.length; i++) {
12      
13      if(brr[i] <=  brr[i+1]) {
14        m = brr[i];
15        n = brr[i+1];
16      } else {
17        m = brr[i+1];
18        n = brr[i];
19      }
20     
21     
22     //求兩個數的最大公約數
23      c = m, e = n, f = c;
24      while(c !== 0) {
25       f = e % c;
26       e = c;
27       c = f;
28      }
29      
30      //求兩個數的最小公倍數
31      var d = m * n / e;
32      //alert(d);
33      brr.splice(0,2,d);
34 
35 
36      if(brr.length === 1) {
37       num = d;
38       break;
39      }
40      i = -1;
41   }
42 
43   console.log(num);
44   return num;
45 }

函數smallestCommons()接收一個數組參數,這個數組包含兩項,這個函數的作用是找出這兩項之間連續數字的最小公倍數,最后返回這個最小公倍數。

比如:

smallestCommons([1, 13]);//返回 360360。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM