zoukankan      html  css  js  c++  java
  • 面试题-分解质因数

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

     

     

    总结:

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

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

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

    作者:徐飞
    出处:www.cnblogs.com/xumanbu/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    poj 1456 Supermarket (最短路程)
    poj 1251Jungle Roads (最小生成树:prime+krusual)
    poj 2677 Tour (最短路)
    poj 2485Highways (求最长路)
    一位ACMer过来人的心得
    poj 2395 Out of Hay (最小生成树的最大边)
    poj 1703 Find them, Catch them (并查集)
    poj 1308 Is It A Tree? (最小生成树)
    poj1258 AgriNet (最小生成树prime)
    poj1789 Truck History (最小生成树)
  • 原文地址:https://www.cnblogs.com/xumanbu/p/4105104.html
Copyright © 2011-2022 走看看