面试题-分解质因数

题目:将一个正整数分解质因数。例如:输入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 }

 

 

总结:

一道面试题,在那半个小时里你能想到这么多?

当然我肯定做不到这么完善,也没有机器调试代码,能写出个思路就差不多了。重点就是这个思路。面试题的结果的往往没有那么重要,但是这个过程和思路很重要。

很多人都说一直做增删改查真没有挑战性,太枯燥,没有意义,从这道题的思考我发现,再简单的事情你能把它做好都很困难。我的解答也许不是最好的,也许很繁琐,但是这个过程我体会很深。欢迎大家评论,发表一下自己的看法。

 

posted @ 2014-11-18 10:35  漫步枫  阅读(1743)  评论(4编辑  收藏  举报