Smith(史密斯)数的求法

先看一下来自百度百科的关于史密斯数的介绍:
美国有一位数字家名叫阿尔伯特·威兰斯基,他姐夫史密斯非常喜欢研究数学,所以两人经常在一起研讨各种数学问题。有时,两人碰不到一起,就习惯性地用电话交流。
一天,两人刚结束电话交谈,史密斯突然灵感来临,对威兰斯基的电话号码“4937775”产生了兴趣,总觉得这是个特别的数。可它的特殊之处究竟在哪儿呢?史密斯开始思索考证起来,他先把4937775分解质因数:4937775=3×5×5×65837,然后再把4937775所有质因数各位上的数字相加得:3+5+5+6+5+8+3+7=42,接着他又把4937775各位上的数字相加得:4+9+3+7+7+7+5=42
秘密终于找到了,原来这两个和相等。这真有意思,难道是巧合么?有没有其他的数也有此特点呢?史密斯不能解答这个问题。不过,他的这一发现引起了许多数学家的浓厚兴趣。数学家们带着这个疑问,纷纷对这一现象进行了研究。
结果发现,有许多数具有这样独特的性质,其中最小的数是4。大家不妨检查一下,4=2×2,2+2=4。类似的有,22=2×11,2+2=2+1+1;27=3×3×3,2+7=3+3+3。随着研究的不断深入,他们发现,在0至10000之间,共有376个这样的数;并且估计在0至100000之间有3300个这样的数。因为这些有趣数的发现,追本溯源是史密斯的功劳,所以数学家们把这样的数叫做“史密斯数”。
现在我们使用Java来求解Smith.在求解的过程发现所有的素数都符合史密斯数的法则。我在0到10000之间找到了1605个史密斯数。
package com.demo;

import java.util.ArrayList;
import java.util.List;

public class Test {

    public static int count = 0;// 统计有多少个史密斯数

    public static void main(String[] args) {

        for (int i = 2; i <= 10000; i++) {
            int sumFac = 0;//每个因数的各个位加和
            int sumPos = 0;// 计算原始数据各个位的和
            int sumPosTemp = i;
            while(sumPosTemp > 0) {
                sumPos += sumPosTemp%10;
                sumPosTemp /= 10;
            }
            List factorizeList = Factorize(i);
            for (Integer fac : factorizeList) {
                int sumFacTemp = fac;
                while(sumFacTemp > 0) {
                    sumFac += sumFacTemp%10;
                    sumFacTemp /= 10;
                }
            }

            if (sumFac == sumPos) {// 如果它俩相等,那么这个数是个史密斯数,输出该数
                System.out.print(i + ",");
                ++count;
                if (count % 5 == 0) {
                    System.out.println();
                }
            }
        }
        System.out.println("\n" + 10000 + "以内共有" + count + "个Simth数!");
    }

    public static List Factorize(int n) {
        int key=1;
        int num=n;
        List list=new ArrayList();  
        while(num > 1){
            for(int i = 2; i <= num; i++){//从2开始除到本身,用于判断素数 
               if(num%i==0){   //找到素数因子  
                   key=i; 
                   list.add(key);  //保存这个素数因子  
                   break;
                }
             }
             num=num/key;     //继续分解除以素数因子得到的商  
        }
        return list;
    }
}

测试结果:
2,3,4,5,7,
11,13,17,19,22,
23,27,29,31,37,
41,43,47,53,58,
59,61,67,71,73,
79,83,85,89,94,
97,101,103,107,109,
113,121,127,131,137,
139,149,151,157,163&#

你可能感兴趣的:(Algorithm)