1. 程式人生 > >求n個數的最大公因數和最小公倍數

求n個數的最大公因數和最小公倍數

     這篇用三種方法求n個數的最大公因數,兩種方法求n個數的最小公倍數

一.程式碼的完成

//求最大公因數和最小公倍數
//功能:用三種方法實現求n個數之間的最大公因數,兩種方法求n個數之間的最小公倍數
//語言:C++
//作者:軟工1502班 賀雪1508010208
//時間:2017年3月18日


#include<iostream>
using namespace std;

//短除法
int Sd_gcd(int num1,int num2,int p)  //p為返回值選擇識別符號
{
    int maxDiv = 1;   //最大公因數賦初值
    for(int i = 2; i <= num1; i ++)   //2為最小質數
    {
        while((num1 % i == 0) && (num2 % i == 0))  //求兩個數的公共因數
        {
            maxDiv = maxDiv * i;   //公共因數相乘
            num1 = num1 / i;
            num2 = num2 / i;
        }
    }
    if(p==1)
		return maxDiv;
	else
		return maxDiv * num1 * num2;
}

//相減法
int Se_gcd(int num1,int num2)
{
	int maxDiv = 1;  //最大公因數賦初值
	int i=1;
	while(i!=0&&num1-num2!=0)  //差等於0結束,maxDiv為等於零前一個值
	{
		if(num1>num2)        //大的減去小的
			i=num1-num2;
		else
			i=num2-num1;
		maxDiv = i;     //差賦給因數
		if(num1>i)       //交換位置,始終保持大的減小的
			num1=i;
		else
			num2=i;
	}
		return maxDiv;
}

//輾轉相除法
int Ea_gcd(int num1,int num2)
{
    int maxDiv = 1;     //最大公因數賦初值
    int Rem;   //餘數
    while(num2 > 0)
    {
        Rem = num1 % num2;
        num1 = num2;
        num2 = Rem;
    }
	return num1;
}

int main()
{
	int m=1;  //m為選擇標識
	int a[10000];  //定義足夠大的空間
	cout<<"求最大公約數和最小公倍數"<<endl;
	cout<<endl;
	while(m==1)
	{
		int x,y,p;
		int maxDiv1,maxDiv2,maxDiv3;
	        int n;  //輸入個數標識
		cout<<"求最大公因數還是最小公倍數:1.最大公因數 2.最小公倍數:";
		cin>>p;
		if(p==1)  //求最大公因數
		{
			cout<<"輸入的整數的個數:";
	        cin>>n;
	        cout<<"輸入數字:";
			for(int j=0;j<n;j++)   //輸入
			{
				cin>>a[j];
			}
			//前兩個數進行比較
			maxDiv1 = Sd_gcd(a[0],a[1],p);   //短除法
			maxDiv2 = Se_gcd(a[0],a[1]);   //相減法
			maxDiv3 = Ea_gcd(a[0],a[1]);   //輾轉相除法
	        cout<<endl;
			for(j=2;j<n;j++)   //兩兩進行比較
			{
				maxDiv1 = Sd_gcd(maxDiv1,a[j],p);  //短除法
				maxDiv2 = Se_gcd(maxDiv2,a[j]);   //相減法
				maxDiv3 = Ea_gcd(maxDiv3,a[j]);   //輾轉相除法
			}
			cout<<endl;
			cout<<"最大公因數是(短除法):"<<maxDiv1<<endl;
			cout<<"最大公因數是(相減法):"<<maxDiv2<<endl;
			cout<<"最大公因數是(輾轉相除法):"<<maxDiv3<<endl;
			cout<<endl;
		    cout<<"請選擇:1.繼續計算 2.結束:";   //選擇結束或繼續
		    cin>>m;
			cout<<endl;
		}
		else
		{
			int s;
			int minMul;  //最小公倍數
	        int a[10000];  //定義足夠大的空間
	        int n;  //輸入個數標識
	        cout<<"輸入的整數的個數:";
	        cin>>n;
	        cout<<"輸入數字:";
			for(int j=0;j<n;j++)   //輸入
			{
				cin>>a[j];
			}


			//最小公倍數等於短除法所有質數相乘,即最大公因數乘兩數剩餘的兩個質數
			minMul = Sd_gcd(a[0],a[1],p);  
			for(j=2;j<n;j++)   //兩兩進行比較
			{
				minMul = Sd_gcd(minMul,a[j],p);
			}
			cout<<endl;
			cout<<"最小公倍數是(質數相乘):"<<minMul<<endl;


			//最小公倍數等於兩個數之積除以最大公因數
			s=(a[0]*a[1])/Ea_gcd(a[0],a[1]);  //也可呼叫Se_gcd(),即用相減法計算最大公因數
            for(int i=2;i<n;i++)   //兩兩比較
			{
				s=((s*a[i])/Ea_gcd(s,a[i]));
			}
			cout<<"最小公倍數是(兩數之積除以最大公因數):"<<s<<endl;
			cout<<endl;
			cout<<"請選擇:1.繼續計算 2.結束:";   //選擇結束或繼續
			cin>>m;
			cout<<endl;
		}
	}
	return 0;
}

二.執行截圖(改進過程)

第一步 只求兩個數的最大公因數:

第二步: 求兩個數的最大公因數和n個數的最小公倍數: 第三步 求出了n個數的最大公因數和n個數的最小公倍數:

三.個人總結

    

    這次的作業完成的速度比較快,首先,完成了對於兩個數之間求最大公因數的計算,然後拓展了對於n個數求最小公倍數,接著改良了公因數,改為可以求n個數的最大公因數和n個數的最小公倍數。

這次作業對於數學的要求比較高,對於如何求最大公因數最小公倍數的方法,我只侷限於以前學習的簡單的方法,沒想到有很多很多,輾轉相除法、相減法等等,對於數學的積累太薄弱是自己的一大弱點,所以對於要用三種方法求最大公因數和最小公倍數,我還在網上找了求證的方法,才補充了知識盲點。

在程式設計過程中,對於求兩個數之間的公因數和公倍數,都比較簡單,但是拓展到n個的時候,就遇到了障礙,一開始總是想著怎麼能直接對於n個數的比較,運用陣列,直接用a[j]a[j+1]進行比較,然後j++,執行後發現,如果直接j++,在a[j]a[j+1]計算後,a[j+2]又和a[j+1]重複計算,邏輯完全錯誤,所以這種想一步登天的想法太可笑,最後先把第一個數和第二個計算出結構後,用結果去和j+1計算,就可以避免重複的後果,克服了這個問題以後,我完成了求n個數的最小公倍數,於是便試著將求最大公因數的功能也擴充套件到可以同時求n個數的,最終完成了對n個數求最大公因數和最小公倍數的程式,但是對於對輸入資料正確性的驗證,卻沒有完善。

這是最基礎的ACM題,以後要自己多找題練習,加強自己的邏輯計算能力。