Steinアルゴリズムは最大公約数を求めます
1428 ワード
最大公約数を求めるアルゴリズムといえば、多くの人が転々と相殺法、すなわちユークリッドアルゴリズムを思い出し、アルゴリズム思想は以下の通りである.
2つの整数a,bを与えて、aとbの最大公約数を求め、dがaとbの公約数であれば、aもbとa%bの公約数であり、逆にaがbとa%bの公約数であれば、bもaとbの公約数であり、この考えを利用して、アルゴリズムは以下のように実現される.
このアルゴリズムは,マシンワード長タイプの整数に対しては比較的効率的であるが,大きな整数(bigint)タイプを扱う場合には除算演算が必要となり,さらにいくつかのワード長を前に処理するとCPU時間が浪費され,Steinアルゴリズムではシフトと減算で処理され,除算演算がないため,最大公約数を求める場合には比較的効率的である.Steinアルゴリズムの原理は以下の通りである.
1.aとbが偶数であれば、公約数2を記録し、2を除いた(すなわち、右シフト1ビット).
2.いずれかの数が偶数であれば、偶数は2を除きます.この場合、2はこの2つの数の公約数ではないからです.
3.両方が奇数であれば、a=|a−b|,b=min(a,b)であり、dがaとbの公約数であれば、dもa−bとmin(a,b)の公約数であるからである.
以上の原理に基づいて、再帰アルゴリズムは以下のように実現される.
参照先:
http://www.cnblogs.com/drizzlecrj/archive/2007/09/14/892340.html
http://blog.henix.info/blog/stein-gcd-algorithm.html
2つの整数a,bを与えて、aとbの最大公約数を求め、dがaとbの公約数であれば、aもbとa%bの公約数であり、逆にaがbとa%bの公約数であれば、bもaとbの公約数であり、この考えを利用して、アルゴリズムは以下のように実現される.
int gcd(int a, int b) {
int t, r;
if(a < b){
t = a;
a = b;
b = t;
}
while(b != 0) {
r = b;
b = a % b;
a = r;
}
return a;
}
このアルゴリズムは,マシンワード長タイプの整数に対しては比較的効率的であるが,大きな整数(bigint)タイプを扱う場合には除算演算が必要となり,さらにいくつかのワード長を前に処理するとCPU時間が浪費され,Steinアルゴリズムではシフトと減算で処理され,除算演算がないため,最大公約数を求める場合には比較的効率的である.Steinアルゴリズムの原理は以下の通りである.
1.aとbが偶数であれば、公約数2を記録し、2を除いた(すなわち、右シフト1ビット).
2.いずれかの数が偶数であれば、偶数は2を除きます.この場合、2はこの2つの数の公約数ではないからです.
3.両方が奇数であれば、a=|a−b|,b=min(a,b)であり、dがaとbの公約数であれば、dもa−bとmin(a,b)の公約数であるからである.
以上の原理に基づいて、再帰アルゴリズムは以下のように実現される.
int sgcd(a, b) {
int t;
if(a < b){
t = a;
a = b;
b = t;
}
if(b == 0) return a;
if(a % 2 == 0 && b % 2 == 0){
return 2 * sgcd(a / 2, b / 2);
} else if(a % 2 == 0 && b % 2 != 0){
return sgcd(a / 2, b);
} else if(a % 2 != 0 && b % 2 == 0){
return sgcd(a, b / 2);
} else {
return sgcd(a-b, b);
}
}
参照先:
http://www.cnblogs.com/drizzlecrj/archive/2007/09/14/892340.html
http://blog.henix.info/blog/stein-gcd-algorithm.html