只能从一些特殊的性质去找。比如找因子的时候,最多只循环到这个数的一半向上取整。因为一个数除以他本身一半的以上的数的时候,因子只会是他本身和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;
}
}