Java 亲密数

有兄弟学Java,问我怎么算3000以内的亲密数(亲密数是什么?A的因子之和等于B,B的因子之和等于A,A与B互为亲密数)。

记得当初有一版标准答案:

class Qinmin1{

    static void fun1(int range) {
        long start = System.currentTimeMillis();
        for(int i=1;i<range;i++){
            int aSum=0,bSum=0;
            for(int a=1;a<=i/2;a++){
                if(i%a==0){
                    aSum+=a;
                }
            }
            for(int b=1;b<=aSum/2;b++){
                if(aSum%b==0){
                    bSum+=b;
                }
            }
            if(bSum==i&&i<aSum){
                System.out.println(i+" 和 "+aSum+" 互为亲密数!");
            }
        }
        System.out.println("Qinmin1.fun1运行用时:"+(System.currentTimeMillis()-start)+"ms.");
    }

}

 但是标准答案也不一定是完美的,当题目要求计算的不是3000,而是2700,或者5100时,会出现一个问题:

220 和 284 互为亲密数!
1184 和 1210 互为亲密数!
2620 和 2924 互为亲密数!
Qinmin1.fun1运行用时:31ms.
220 和 284 互为亲密数!
1184 和 1210 互为亲密数!
2620 和 2924 互为亲密数!
5020 和 5564 互为亲密数!
Qinmin1.fun1运行用时:70ms.

发现了吗?2924和5564是超出了范围的。于是代码修改为

class Qinmin2{

    static void fun2(int range) {
        long start = System.currentTimeMillis();
        for(int i=1;i<range;i++){
            int aSum=yinziSum(i);
            if(yinziSum(aSum)==i&&i<aSum&&aSum<range){
                System.out.println(i+" 和 "+aSum+" 互为亲密数!");
            }
        }
        System.out.println("Qinmin3.fun3运行用时:"+(System.currentTimeMillis()-start)+"ms.");
    }

    private static int yinziSum(int num){
        int sum = 0;
        for(int i=1;i<=num/2;i++){
            if(num%i==0){
                sum+=i;
            }
        }
        return sum;
    }
}

虽然代码风格跨度有点大,但是抽取重复代码不应该是一个资深菜鸟应该做到的吗?这不是重点,判断条件才是。

至此代码写完了。但是还有问题,一些数字的因子和被计算了不止一遍,这怎么行,性能啊!!!

为了只计算一次,再次修改代码:

class Qinmin3{
    static void fun3(int range){
        long start = System.currentTimeMillis();
        Map<Integer,Integer> yinziMap = new HashMap<>();
        for(int i=1;i<range;i++){
            yinziMap.put(i,yinziSum(i));
        }

        for (Integer key:yinziMap.keySet()) {
            if(Objects.equals(yinziMap.get(yinziMap.get(key)), key)
                    &&key.compareTo(yinziMap.get(key))<0){
                System.out.println(key+" 和 "+yinziMap.get(key)+" 互为亲密数!");
            }
        }
        System.out.println("Qinmin2.fun2运行用时:"+(System.currentTimeMillis()-start)+"ms.");
    }

    private static int yinziSum(int num){
        int sum = 0;

        for(int i=1;i<=num/2;i++){
            if(num%i==0){
                sum+=i;
            }
        }

        return sum;
    }
}

用一个map将每个数字的因子之和装起来,不就能只计算一次了吗?用空间换时间啊。虽然对于刚入门的菜鸟来说有点超纲,但性能大大提高了,至少节省一半运行时间。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值