如果一个正整数恰好等于它所有的真因子(即除了自身以外的因子)之和,则称之为完美数(完全数)。例:6=1+2+3
欧几里德完全数定理:若p、(2的p次幂-1) 这两个值均为素数,则 2的(p-1)次幂 乘以 (2的p次幂-1) 的值是个完美数。
利用上面的算法(定理)编程实现求1~10000范围内的完美数如下:
package com.learn.arithmetic; public class PerfectNumber { /** * @param args */ public static void main(String[] args) { for (long p = 2; p <= 31; p++) { if (!pri(p)) { continue; } long t = 2; for (int k = 1; k < p; k++) { t = t * 2; } long j = t / 2; t--; if (pri(t)) { System.out.println(j + " * " + t + " = " + (j * t)); } } normal(); } // 八个完美数 // 3 * 2 = 6 // 7 * 4 = 28 // 31 * 16 = 496 // 127 * 64 = 8128 // 8191 * 4096 = 33550336 // 131071 * 65536 = 8589869056 // 524287 * 262144 = 137438691328 // 2147483647 * 1073741824 = 2305843008139952128 /** * 判断传入的参数是否是一个素数 * * @param suShu * @return true=是,false=不是 */ public static boolean pri(long suShu) { int q = (int) Math.sqrt(suShu) + 1; for (int i = 2; i <= q; i++) { if (suShu % i == 0 && suShu != 2) { return false; } } return true; } /** * 求10000以内的完美数,普通的算法。 * 找到后,显示成和的形式。 */ public static void normal() { for (int i = 6; i < 10000; i++) { int s = 0; for (int j = 1; j <= i / 2; j++) { if (i % j == 0) { s += j; } } if (s == i) { System.out.print(s + " = 1"); for (int j = 2; j <= i / 2; j++) { if (i % j == 0) { System.out.print(" + " + j); } } System.out.println(); } } } }
小结:我们知道,程序=数据结构+算法。如果,我们要使得设计的程序显得简洁而高效,那么就需要我们有足够的数学功底和数据结构知识的灵活运用能力。
例如:求解1~100的自然数之和。
1)不知道高斯求和公式的程序员会这样编码实现:
2)掌握了高斯求和算法(公式)的程序员会这样编程实现:int i; int j=100; int sum=0; for(i=1;i<=j;i++){ sum+=i; } System.out.println("1~100自然数之和为:"+sum);
int sum=0; sum=(1+100)*100/2; System.out.println("1~100的自然数之和为:"+sum);
由此可知,会算法的程序员比起那些只会硬套(不会或者根本不去使用算法)的程序员要高效许多。
完美数
最新推荐文章于 2018-05-03 12:32:31 发布