算法题练习(完数、是否合数、水仙花数)

【程序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 的真因子。

为此,我们的内层循环,可以这样优化:

算法题练习(完数、是否合数、水仙花数)_第1张图片

【程序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);
            }
        }
    }
    

 

你可能感兴趣的:(算法)