最大約數問題—java版

  問題描述:正整數x的約數是能整除x的正整數。正整數x的約數個數記爲div(x)。例如,10有4個約數:1、2、5、10。設a和b是兩個正整數,試計算a和b之間約數個數最多的數x。

    問題分析:

    首先以10、20、30這幾個數的約數情況來分析約數的個數。

        10=2*5;10有1、2、5、10共4個約數;

        20=2^2*5;20有1、2、4、5、10、20共6個約數;

        30=2*3*5;30有1、2、3、5、6、10、15、30共8個約數。

 

    在上述三個數中,可以發現,每一個數都可以分解爲若干個質數(素數)的乘積,而所有的約數中,除了1以外,其他所有的數都可以看成這些質數的乘積,而1可以看成是相關的質數的冪爲0的情況。以10和20爲例來說明這個問題:

    10的4個約數中,可以看成如下的情況:

        1=2^0*5^0

        2=2^1*5^0

        5=2^0*5^1

        10=2^1*5^1

    20的6個約數中,可以看成是如下的情況:

        1=2^0*5

        2=2^1*5^0

        4=2^2*5^0

        5=2^0*5^1

        10=2^1*5^1

        20=2^2*5^1

    從這兩個例子中可以發現,如果可以確定相關質數的指數,則這個數的約數的個數爲相關指數加1後相乘。如10的約數數目爲(1+1)*(1+1)=4,20的約數數目爲(2+1)*(1+1)=6。

    參考程序如下:

import java.util.ArrayList;

import java.util.List;
import java.util.Scanner;


/**
 * 定義一個類爲冪函數類,類中包含兩個參數
 * @author LiuYong
 * 算法思路:根據每個數都可以分解爲一個或多個質因子相乘的積的形式這一理論,
 * 可以將每個數的因子個數表達爲每個質因子出現的次數加1相乘的形式
 * */
class  Monomial { 
int base;//冪函數的底數
int index;//冪函數的指數
//無參構造函數
public Monomial(){

}
//帶參構造函數
public Monomial(int base,int index){
this.base=base;
this.index=index;
}
//用於計算輸入的數的因子個數,根據以上所表達的算法思路進行
public int Count(List<Monomial> list) {
int count=1;//計算出的因子個數
for(int i=0;i<list.size();i++){//將鏈表中存放的質因子對象遍歷出來
count=count*((list.get(i).index)+1);//根據算法說明對每個質因子指數加一然後求積
}
return count;//返回因子個數
}
}




/**
 * 定義一個整數類,類中包含三個參數,還有一個用於整數分解的方法
 * @author LiuYong
 * 算法思路:每個整數都可以分解爲一個或多個質因子的冪函數相乘的形式,
 * 輸入一個需要處理的整數,利用for循環,從最小的非一整數開始遍歷,
 * 當餘數爲零時說明爲質因子可以保留並將其作爲一個對象保存,然後用商
 * 繼續除以當前的除數,如果餘數不爲一則將除數加一,按照上述描述循環
 * 直到除數大於被除數時算法結束
 *  @param conunt代表某一整數同一個質因子出現的次數(被除的次數)
 *  @return 返回一個攜有該整數所有質因子對象的鏈表list
 */
class IntegerWhole{
List<Monomial> list;//定義一個鏈表來裝載所有的質因子對象,但不可以初始化因爲一旦初始化,第二個數向鏈表中添加質因子從已經初始化的鏈表後邊繼續插入,而不是從0開始
int temp=2;//除數
Monomial monomial;//未實例化對象
public List<Monomial>  factorization(int number){
list=new ArrayList<Monomial>();
   for(int i=2;i<=number;i++){
    int remainder=0;//初始化餘數,只能將他當做這個類的局部變量,如果是全局變量就會產生和list一樣的效果
    int count=-1;//初始化整數的同一個質因子出現的次數,值爲-1,也可以爲零,爲零時count要放到if語句裏
    while(remainder==0){
    remainder=number%i;//求出餘數,如果餘數爲0代表i爲number的質因子,否則不是
    if(remainder==0){//限制條件:只有當餘數爲零時,即i爲質因子,纔將number再次除以質因子來得到下一個數來參與質因子的求得
    number/=i;//將商賦值給number,繼續向下取質因子
    }
    count++;
    }
    monomial=new Monomial(i,count);//初始化一個冪函數對象,並將底數與指數傳進去
    list.add(i-2, monomial);//將初始化的冪函數對象加到鏈表中
   }

return list;
}
}


/**
 * 作爲一個判斷類,擁有一個判斷方法用於判斷給定的正整數中質因子最多的那個,並將其輸出
 * @author LiuYong
 * @param a,b  分別初始化出來接收稍小正整數min與稍大正整數max兩個數的質因子個數
 * @version 2013-9-1  下午2:32:17
 */
class Judge{
IntegerWhole intwho=new IntegerWhole();
Monomial mon=new Monomial();
//初始化a,b
int a=0;
int b=0;
/**
* 用於判斷輸入的兩個數中質因子最多的個數並將其返回
*  @return  返回一個字符串,既可以是提示語句也可以是質因子最多的個數
*/
public String judgeMax(int min,int max){
if(min<=max){//攔截所有不滿足a<b這一題意的參數,並返回一句提示語句
if(min<=0||max<=0){//攔截所有不是正整數的參數,並返回一句提示語句
return "比較的兩個數不得有一個爲非正整數!";
}else{
a=mon.Count(intwho.factorization(min));//求出較小值的質因子個數
b=mon.Count(intwho.factorization(max));//求出較大值的質因子個數
return a<b?Integer.toString(b):Integer.toString(a);//返回字符串形式質因子個數
}
}else{
return "沒有滿足‘a<=b’的題意";
}
}


}




/**
* 主幹思路:知道質因子出現的次數(需要有一個冪函數類)-->根據質因子的指數計算因子個數(需要一個整數類)-->將兩個得到的因子數進行比較得出最大者(需要一個判斷類)
* @author LiuYong
* @version 2013-9-1  下午3:29:54
*/
public class Section1_3{
public static void main(String[] args) {
Judge judge=new Judge();
Scanner scan=new Scanner(System.in);
System.out.println("請輸入要比較的兩個數");
int sca1=scan.nextInt();
int sca2=scan.nextInt();
System.out.println(judge.judgeMax(sca1, sca2));
}
}
發佈了16 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章