【程序9】题目:一个数如果恰好等于它的真因子之和,这个数就称为“完数”。例如6=1+2+3。编程找出1000以内的所有完数。
@Test public void test07() { int s; for (int i = 1; i < 1000; i++) { s = 0; /** * 1 一定是所有数的真因子; * 因为是真因子,所以判断因子的这一步要小于i */ for (int j = 1; j < i; j++) { if (i % j == 0) { s = s + j; } } if (s == i) { System.out.println("1000以内的完数有:" + i); } } }
得到的输出结果是:
1000以内的完数有:6
1000以内的完数有:28
1000以内的完数有:496
优化:利用直观的想法。
其实寻找 i 的真因子,我们使用的是循环,从1到 i-1 ,其实这里只需要判断到 i/2 就可以了。这是因为,在正数 i 的所有真因子中, 最大的真因子肯定不会超过 i / 2 。
这样可以减少内层循环的次数。
分析:如果这个数是一个奇数,例如 23:
23/2=12,判断到 12 不是 23 的真因子,就没有必要去判断 13 、 14 、15 直到 22 是不是 23 的真因子。
如果这个数是偶数 例如 24 :
24/2=12,同样地,判断到 12 是 24 的真因子,也没有必要去判断 13 、 14 、15 直到 22 是不是 23 的真因子。
为此,我们的内层循环,可以这样优化:
【程序2】程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素数。
@Test public void test08(){ System.out.println(isZhiShu(7)); } public boolean isZhiShu(int x){ for(int i=2;i<=Math.sqrt(x);i++){ if(x%i==0){ return false; } } return true; }
分析:这里要用到一个数学结论。如果一个数是合数,那么它必有一个素因子小于等于它的平方根。证明如下。
设 n=pq 是合数,且 1<p<q ,则 p^2<pq=n ,则 p<Math.sqrt(n) 。(证完)
关于整除的理论,可以参考下面的文章:
初等数论 第一章 整除理论_百度文库
http://wenku.baidu.com/link?url=oKZ4jRKHrPAGocTc15M1A5uFRJmI4CwgX6sRZeKs-c_wwNG_wWV6bxoRVzzSFeltM1moFy4ihocif9UL2zBD4vTuoMpxQZcqIYfeuxLgORu
【程序3】题目:打印出所有的“水仙花数”,所谓“水仙花数”是指一个三位数,其各个位数字的立方和等于该数本身。例如:153是一个“水仙花数”,因为153=1的三次方+5的三次方+3的三次方。
程序分析:利用for循环控制100-999个数,每个数分解出个位,十位,百位。
@Test public void test09(){ int x,y,z;// 个位、十位、百位 for(int i =100;i<1000;i++){ x = i % 10; // 个位 z = i / 100 ; // 百位 // y = (i - 100*z - x)/10; // 这一步还可以优化 y = (i%100)/10; if(i== (Math.pow(x, 3) + Math.pow(y, 3) + Math.pow(z, 3))){ System.out.println("1000 以内的水仙花数有:" + i); } } }