求1-99999999之间的完美数


该怎么优化,才能使计算量减下来,这个程序算到100000时间非常长了(好像还有点小问题,大佬帮忙看一下)

只能从一些特殊的性质去找。比如找因子的时候,最多只循环到这个数的一半向上取整。因为一个数除以他本身一半的以上的数的时候,因子只会是他本身和1。 1从一开始已经本找过了。他本身也不需要找。 这样循环量直接减少一半。


package com.wanmei;

public class WanMei {

    public static void main(String[] args) {
        
        long start = System.currentTimeMillis();
        
        int n = 99999999;
        int end = (int)(Math.log10(n) / Math.log10(2));
        
        //因为偶完全数有很好的性质,先找偶完全数
        //对于偶完全数,如果p是素数,同事2的 p方减1也是素数,
        //那么(2^p-1)X2^(p-1)便是一个完全数
        for (int i = 2; i <= end; i++) {
            if(isPrime(i)){
                int pow = (int)Math.pow(2, i) ;
                int tmp = pow - 1;
                if(isPrime(tmp)){
                    int wanmei = (pow / 2 ) * tmp;
                    if(wanmei > 0){
                        //有可能溢出,所以加个判断
                        System.out.println("偶完美数: " + wanmei);
                    }
                }
            }
        }
        //处理奇数
        //若 n为奇完全数,则 n= 12m+1 或 n=36m+9,m为正整数
        
        boolean flag = false;
        //处理 12m+1
        int end2 = (n-1) / 12 ;
        for (int m = 12; m <= end2; m+=12) {
            
            int num = m + 1;
            if(num > n || num < 0){
                //超过n或者溢出int范围
                break;
            }
            int sum = 1;
            
            int end1 = (int) Math.sqrt(num);
            for (int j = 3; j <= end1; j+=2) {
                if(num % j == 0){
                    sum += j;
                    if (j != num / j){
                        //一对相同的只加一次
                        sum += num/j;
                    }
                    
                }
                if(sum > num){
                    
                    break;
                }
            }
            if(sum == num){
                flag = true;
                System.out.println("奇完美数: " + num);
            }
        }
        
        //处理 36m+9
        int end3 = (n-9) / 36 ;
        for (int m = 36; m <= end3; m+=36) {
            int num = m + 9;
            if(num > n || num < 0){
                //超过n或者溢出int范围
                break;
            }
            int sum = 1;
            
            int end1 = (int) Math.sqrt(num);
            for (int j = 3; j <= end1; j+=2) {
                if(num % j == 0){
                    sum += j;
                    if (j != num / j){
                        //一对相同的只加一次
                        sum += num/j;
                    }
                    
                }
                if(sum > num){
                    
                    break;
                }
            }
            if(sum == num){
                flag = true;
                System.out.println("奇完美数: " + num);
            }
        }
        if(!flag){
            System.out.println("在给定范围内没有奇完全数");
        }
        
        long endtime = System.currentTimeMillis();
        
        System.out.println("耗时: " + ((endtime - start) / 1000));
    }

    private static boolean isPrime(int num) {
        if(num == 2 || num == 3){
            return true;
        }
        
        if(num %6!= 1&&num %6!= 5){
             return false ;
        }
           
        int end = (int)Math.sqrt(num);
        for (int i = 5; i <= end; i+=6) {
            if(num %i== 0||num %(i+ 2)==0 ){
                return false ;
            }
                
        }
        
        return true;
    }
}

img