java求一个数的因子

        java算一个数的所有因子。

        最简单粗暴的方法:从1遍历到num,如果能被num整除,就是num的因子。

//该方法传入两个参数。一个是num(求num的因子);一个是arr数组,用来存放num的因子
    public static void fun1(int num,ArrayList<Integer> arr){

        for ( int i = 1 ; i <= num ; i++ ){
            if ( num % i == 0 ){
                arr.add(i);    //将因子存放到arr数组中

            }
        }

    }

        显而易见,当num的值较小的时候,该方法非常简单。但是,如果num非常的大,那么,这个算法的时间是非常久的。

        我们来测试一下,当num的值为999999999(9位数)时,程序用时大概1650毫秒。已经大于1秒钟,产生肉眼可见的延迟。

int num = 999999999;
ArrayList<Integer> arr = new ArrayList<>();

long startTime = System.currentTimeMillis();    //开始
fun1(num,arr);
long endTime = System.currentTimeMillis();      //结束

System.out.println(endTime - startTime);

        所以刚刚的算法肯定是不行的。那么优化后的算法如下:

public static void fun(int num,ArrayList<Integer> arr){

        //从1遍历到num的平方跟即可。
        //这时你可能会说,那后面的数呢,比如num本身,不是计算不到了嘛?
        //别急,看for循环里面的处理情况

        for ( int i = 1 ; i <= Math.sqrt(num) ; i++ ){

            //如果能被num整除,那肯定是num的因子,毫无疑问
            if ( num % i == 0 ){
                arr.add(i);

                //重点的部分在这里!!!
                //当i能被num整除的情况下,此时i是相对较小的因子,用i求出num另一个较大的因子n
                //因为当i能被num整除时,那么数"num/i"也一定能被num整除
                //不需要再进行重复的计算,这样算法的运行时间大大降低

                int n = num / i;

                //但用i算出另一个较大的因子时,会出现重复的情况
                //例如num = 4,当遍历到2时,算出另一个较大的因子也是2,这就重复了,要判断一下

                if ( n != i ){    
                    arr.add(n);
                }

            }
        }

    }

        我们再来试试这个算法的运行时间。差不多1毫秒,明显比上一个算法快非常多。

int num = 999999999;
ArrayList<Integer> arr = new ArrayList<>();

long startTime = System.currentTimeMillis ();    //开始
fun(num,arr);
long endTime = System.currentTimeMillis ();      //结束

System.out.println(endTime - startTime);

        我们再来看看两个算法得到的因子是否相同:

        写一个方法用于输出数组。

public static void printf(ArrayList<Integer> arr){

        Collections.sort(arr);  //给因子从小到大排序,方便查阅
        for ( int i = 0 ; i < arr.size() ; i++ ){
            System.out.print(arr.get(i)+" ");
        }
        System.out.println("");

    }

        主程序:

        定义两个数组,数组arr存放优化算法得到的因子,数组arr1存放旧算法得到的数组。

int num = 999999999;

ArrayList<Integer> arr = new ArrayList<>();
ArrayList<Integer> arr1 = new ArrayList<>();

fun(num,arr);
printf(arr);

fun1(num,arr1);
printf(arr1);

        输出结果:

1 3 9 27 37 81 111 333 999 2997 333667 1001001 3003003 9009009 12345679 27027027 37037037 111111111 333333333 999999999 
1 3 9 27 37 81 111 333 999 2997 333667 1001001 3003003 9009009 12345679 27027027 37037037 111111111 333333333 999999999 

        可以看到一模一样,所以说优化过后的算法是非常好的。而且,我在运行程序时,第一个数组arr(优化算法)的输出非常的快,肉眼无法捕捉。而第二个数组(旧算法)的输出延迟特别明显。

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值