面試題-分解質因數


題目:將一個正整數分解質因數。例如:輸入90,打印出90=2*3*3*5   
程序分析:對n進行分解質因數,應先找到一個最小的質數k,然后按下述步驟完成:   
(1)如果這個質數恰等於n,則說明分解質因數的過程已經結束,打印出即可。   
(2)如果n <> k,但n能被k整除,則應打印出k的值,並用n除以k的商,作為新的正整數你n,重復執行第一步。   
(3)如果n不能被k整除,則用k+1作為k的值,重復執行第一步。  

網上這道題一搜就能找到,但是我看到的一個答案是這樣的:

 

 1 import java.util.Scanner;

 2

 3 public class lianxi04 {

 4     public static void main(String[] args) {

 5         Scanner s = new Scanner(System.in);

 6         System.out.print("請鍵入一個正整數:     ");

 7         int n = s.nextInt();

 8         int k = 2;

 9         System.out.print(n + "=");

10         while (k <= n) {

11             if (k == n) {

12                 System.out.println(n);

13                 break;

14             } else if (n % k == 0) {

15                 System.out.print(k + "*");

16                 n = n / k;

17             } else {

18                 k++;

19             }

20         }

21     }

22 }

 

 這道題本身並沒有什么難度,只要思路對了無論使用遞歸還是循環都可以解決。順便說一下解題思路吧。接受一個輸入的數字,就是被分解的數字(num),最小的質子數是2,然后num除以2,如果可以整除,2就是一個質因數,如果不可以2+1,再拿num除以進行整除判斷。對所得的質因數輸出。

這么寫當然是可以得出正確答案的,但是想一想,這樣的代碼好嗎?

以上代碼有以下幾點不好的地方:

1、 所有代碼都寫到了main中,這個是很不好的習慣,main方法一般就是做啟動jvm用的不應該含有業務邏輯;

2、 請接受一個用戶輸入的數字從控制台接收,如果這個輸入的數據是從一個界面或者網絡來的,那這個程序不是得整體改動,獲取處理數據應該是有一個方法封裝。

3、 從控制台接收數據,獲得的數據類型是int,但是以上程序在輸入a這樣的非int數據會拋異常,沒有做異常處理,這個異常打印很不友好;

4、 分解質因數這個功能應該也算是一個算法,這個算法為了能夠被可重復使用,需要進行封裝;

5、 同理輸出的方法也應該需要進行封裝,題目雖然是輸出道控制台,但是如果哪天需求變動,不是慘了。(該死的需求總是在變,大家應該都有體會);

6、 變量的命名:n,k誰能理解這個是什么意思啊。

 

下面是我對這道題解答的改進:

涉及五個類:

PrimeHandle:分解質因數處理類,核心算法

Input:獲取輸入數據的接口

ConsoleInput:從控制台輸入數據的Input接口實現

Output:輸出結果的接口

ConsoleOutput:從控制台輸出結果的Output接口實現

Main:客戶端程序,用於執行程序

 

上代碼:

 1 public class PrimeHandle {

 2    

 3     //用於存放結果

 4     private List<Integer> results = new ArrayList<Integer>();

 5     //需要處理的數字

 6     private int handleNum;

 7     //最小的質子數

 8     private static final int minPrime = 2;

 9    

10     PrimeHandle(int handleNum){

11         this.handleNum = handleNum;

12     }

13    

14     //獲得因子的方法

15     private void analyse(int num,int primeNum){

16         if(num<=primeNum){

17             results.add(num);

18         }else{

19             if(num%primeNum==0){

20                 results.add(primeNum);

21                 analyse(num/primeNum,minPrime);

22             }else{

23                 primeNum++;

24                 analyse(num,primeNum);

25             }

26         }

27     }

28    

29     //獲得結果

30     public String getResult(){

31         analyse(handleNum,minPrime);

32         StringBuilder resultStr = new StringBuilder();

33         for(int i:results){

34             resultStr.append(i+"*");

35         }

36         if(resultStr.length()>0){

37             return resultStr.substring(0,resultStr.length()-1);

38         }else{

39             return "";

40         }

41     }

42    

43 }

44

45 public interface Input {

46     int getHandleNum();

47 }

48

49

50 public class ConsoleInput implements Input {

51

52     public int getHandleNum() {

53         int inputNum = 0;

54         Scanner scanner = new Scanner(System.in);

55         System.out.print("請輸入一個數字:");

56         try{

57             inputNum = scanner.nextInt();

58         }catch(Exception e){

59             System.out.println("輸入數據有誤,請重新輸入!");

60             inputNum = this.getHandleNum();

61         }

62         return inputNum;

63     }

64

65 }

66

67 public interface Output {

68     void out(String result);

69 }

70

71 public class ConsoleOutput implements Output {

72

73     public void out(String result) {

74         System.out.println("的因式分解為:"+result);

75     }

76

77 }

78

79 public class Main {

80     public static void main(String[] args) {

81         Input input = new ConsoleInput();

82         int handleNum = input.getHandleNum();

83         PrimeHandle handle = new PrimeHandle(handleNum);

84         String resultStr = handle.getResult();

85         Output output = new ConsoleOutput();

86         output.out(resultStr);

87        

88     }

89 }

 

 

總結:

一道面試題,在那半個小時里你能想到這么多?

當然我肯定做不到這么完善,也沒有機器調試代碼,能寫出個思路就差不多了。重點就是這個思路。面試題的結果的往往沒有那么重要,但是這個過程和思路很重要。

很多人都說一直做增刪改查真沒有挑戰性,太枯燥,沒有意義,從這道題的思考我發現,再簡單的事情你能把它做好都很困難。我的解答也許不是最好的,也許很繁瑣,但是這個過程我體會很深。歡迎大家評論,發表一下自己的看法。

 


免責聲明!

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



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