最大公約数の計算__C++


てんかいそうほう
数学では、転々とした相殺法は、ユークリッドアルゴリズム(英語:Euclidean algorithm)とも呼ばれ、最大公約数を求めるアルゴリズムです.転々相除法はユークリッドの「幾何学の元」(第VII巻、命題iとii)に初めて登場し、中国では東漢に現れた「九章算術」にさかのぼることができる.
転がり相除算は、2つの整数の最大公約数が、その中の小さい数と2つの数の差の最大公約数に等しいという原理に基づいている.
アルゴリズムの計算プロセスは次のとおりです.
kは、ステップ数(0からカウント)を示す各ステップの入力が、いずれも前2回計算した非負の剰余rk 1およびrk 2であるとする.各ステップで算出される残数は減少し続けているため、rk−1はrk−2より小さい.ステップkにおいて、アルゴリズムは、rk 2=qk*rk 1+rkのうち0≦rk実装コードは次のとおりです.
//     
int C_commondivisor::div_alg(m_num1, m_num2)
{
	int tmp1 = m_num1;
	int tmp2 = m_num2;
	for (; tmp1 % tmp2 != 0; )
	{
	    tmp1 = tmp1 % tmp2;
	    //tmp1   tmp2 ,tmp1         
	    //               , tmp1     
	    tmp1 = tmp2 - tmp1;
	    tmp2 = tmp2 - tmp1;
	    tmp1 = tmp1 + tmp2;
	}
	return tmp2;
}

転がり相減算転がり相減算(最大公約数を求める)、すなわちニコマンチェス法は、一連の減算を行い、最大公約数を求めるのが特色である.
しかし、私にとっては転々と相殺する「引き算」版のような気がします.
具体的には、次のようになります.
//   
int C_commondivisor::phase_sub()
{
	int tmp1 = m_num1;
	int tmp2 = m_num2;
	for (; tmp1 - tmp2 != 0; )
	{
		tmp1 = tmp1 - tmp2;
		//        ,      tmp1
		if (tmp2 > tmp1)
		{
		    tmp1 = tmp2 - tmp1;
		    tmp2 = tmp2 - tmp1;
		    tmp1 = tmp1 + tmp2;
		}
	}
	return tmp2;
}

貧挙法貧挙法はすべての可能性のある結果を2つの数の中から1つずつ減らし、2つの数で除算された残数が0を満たすかどうかを検証するために持ち込み、一致する最初の数字を見つければ最大公約数となり、最も非効率的で暴力的な方法と言える.
具体的には、次のようになります.
//   
int C_commondivisor::exhaustion()
{
	//             ,                 ,   ,        ,     
	int i = 0;
	for (i = m_num2; i <= m_num2; i--)
	{
		//                ,           ,    
		if ((m_num1 % i) == 0 && (m_num2 % i) == 0)
		{
			break;
		}
	}
	return i;
}

具体的なコードは次のとおりです.
コンパイル実行環境はVisual Studio 2017
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//    : commondivisor.cpp
//    : EL.Gou
//     : 2017.03.21
//     : Visual Studio 2017
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include 

using namespace std;

class C_commondivisor {
public:
	C_commondivisor();
	int input();    //       
	int output(int i);    //    
	int mainmenu();    //    
	int div_alg();    //     
	int phase_sub();    //   
	int exhaustion();    //   
private:
	int m_num1;
	int m_num2;
	int m_result;    //          
};

C_commondivisor::C_commondivisor()
{
	m_num1 = 0;
	m_num2 = 0;
	m_result = 0;
}

//      
int C_commondivisor::input()
{
	cout << "                           :";
	cin >> m_num1;
	cout << "                            :";
	cin >> m_num2;
	cout << "

" << endl; // , m_num1 if (m_num2 > m_num1) { // m_num1 = m_num2 - m_num1; m_num2 = m_num2 - m_num1; m_num1 = m_num1 + m_num2; } return 0; } // int C_commondivisor::output(int i) { cout << "

" << m_num1 << " " << m_num2; if (i == 2) { cout << " "; } else if (i == 3) { cout << " "; } else { cout << " "; } cout << " :" << m_result << "





" << endl; return 0; } // int C_commondivisor::mainmenu() { cout << " " << endl; while (true) { cout << " ”1“" << endl; cout << " ”2“" << endl; cout << " ”3“" << endl; cout << " ”0“" << endl; cout << " , " << endl; cout << "

:"; int tmp = 0; cin >> tmp; if (tmp == 1) { input(); m_result = div_alg(); // } else if (tmp == 2) { input(); m_result = phase_sub(); // } else if (tmp == 3) { input(); m_result = exhaustion(); // } else if (tmp == 0) { break; // , } else { input(); m_result = div_alg(); // , } // output(tmp); } return 0; } // int C_commondivisor::div_alg() { int tmp1 = m_num1; int tmp2 = m_num2; for (; tmp1 % tmp2 != 0; ) { tmp1 = tmp1 % tmp2; //tmp1 tmp2 ,tmp1 // , tmp1 tmp1 = tmp2 - tmp1; tmp2 = tmp2 - tmp1; tmp1 = tmp1 + tmp2; } return tmp2; } // int C_commondivisor::phase_sub() { int tmp1 = m_num1; int tmp2 = m_num2; for (; tmp1 - tmp2 != 0; ) { tmp1 = tmp1 - tmp2; // , tmp1 if (tmp2 > tmp1) { tmp1 = tmp2 - tmp1; tmp2 = tmp2 - tmp1; tmp1 = tmp1 + tmp2; } } return tmp2; } // int C_commondivisor::exhaustion() { // , , , , int i = 0; for (i = m_num2; i <= m_num2; i--) { // , , if ((m_num1 % i) == 0 && (m_num2 % i) == 0) { break; } } return i; } int main(int argc,char** argv[]) { C_commondivisor CCD; CCD.mainmenu(); return 0; }

以上のアルゴリズムと比較して、非常に大きな数字の最大公約数計算を行う場合、steinアルゴリズムはより効率的なアルゴリズムであり、具体的なアルゴリズムの概念と流れは参考にすることができる.http://blog.csdn.net/kemlkyo/article/details/22698597
参考資料:wikipediahttps://zh.wikipedia.org/wiki/%E8%BC%BE%E8%BD%89%E7%9B%B8%E9%99%A4%E6%B3%95#.E6.9C.80.E5.A4.A7.E5.85.AC.E7.BA.A6.E6.95.B0