吸血鬼数字--Java实现探究

来源:互联网 发布:搜索引擎优化wtg168 编辑:程序博客网 时间:2024/05/20 00:49

关于吸血鬼数字,网上有很多的版本,也有最佳实现方式。最近看Java编程思想,又看到了这道题目。于是准备用Java再实现一次,同时和别人代码比较一下,看看自己写的算法究竟有多差劲(汗。。。)

题目:吸血鬼数字是指位数为偶数的数字,可由一对数字相乘而得到,这对数字各包含乘积的一半位数的数字,以两个0结尾的数字是不允许的。 四位数吸血鬼数字示例:1260=21*60,1827=21*87,2187=27*81……

首先大致想了一下,从1000循环到9999,对于每一个数字判断是不是符合,如果是符合则输出。对于每一个4位数,把它看作4个数字,满足条件的一对数字必然是这4个数字的一种排列方式。4个数字排列方式共有 4 != 24 个,9000 * 24 = 216000
这个数字不是特别大,1s内计算机可以跑完,于是。。。我就没多想开开心心的跑去实践了。

敲了好长时间才把代码敲出来,主要是好长时间不练,全排列怎么实现的,记不清了(捂脸)

public class Practice10 {    public static void main(String[] args) {        //老规矩,循环        FullPermutation f = new FullPermutation("");        String s;        int num;        for(int i = 1000; i < 9999; ++i) {            if(i%100 == 0) {                continue;            }            f.setSrc(String.valueOf(i));            while((s = f.nextSequence()) != null) {                num = Integer.parseInt(s);                if(i == ((num/100) * (num%100)))  {                    System.out.println(i + " = " + num);                    break;                }            }        }    }}/** * ps:全排列不用写那么多没用的代码的,一个函数就实现了 * 主要是手贱,想把它写成个类(汗) * */class FullPermutation {    private char ch[];    private char temp[];        private int flag = 0;    FullPermutation(String s) {        ch = s.toCharArray();        flag = 0;    }    FullPermutation(char ch[]) {        this.ch = ch;        flag = 0;    }    FullPermutation(long number) {        ch = String.valueOf(number).toCharArray();        flag = 0;    }    public void setSrc(String s) {        ch = s.toCharArray();        flag = 0;    }    public String nextSequence() {        if(flag >= jc(ch.length)) {            return null;        }        int b = 0;        int len = ch.length;        int tf = flag;        int jctemp = 0;        temp = ch.clone();        for(int i = 0; i < len-1; ++i) {            jctemp = jc(len - i - 1);            b = tf / jctemp + i;            for(int j = b; j > i; --j) {                temp[j] ^= temp[j-1];                temp[j-1] ^= temp[j];                temp[j] ^= temp[j-1];            }            tf %= jctemp;        }        ++flag;        return new String(temp);    }    public String findSequence(int index) {        if(index >= jc(ch.length)) {            return null;        }        int b = 0;        int len = ch.length;        int tf = index - 1;        int jctemp = 0;        temp = ch.clone();        for(int i = 0; i < len-1; ++i) {            jctemp = jc(len - i - 1);            b = tf / jctemp + i;            for(int j = b; j > i; --j) {                temp[j] ^= temp[j-1];                temp[j-1] ^= temp[j];                temp[j] ^= temp[j-1];            }            tf %= jctemp;        }        return new String(temp);    }    private int jc(int x) {        if(x == 1)            return 1;        return jc(x-1) * x;    }}

那么久了,还是有敲代码不写注释的习惯。。。虽然知道不写注释过段时间自己就看不懂了,但就是懒得加啊啊啊。。。

最初程序运行,输出结果有点小问题,把重复的也输出了,打印结果语句后面加了一条break语句后解决。

说实话,跑出来结果还是蛮开心的,然后屁颠屁颠的跑去网上看别人代码,一看才发现自己的SB

在这题中 abcd 与 cdab 是等价的,所以。。。。。
对每一个数字的判断是否符合条件,是 4 * 3 = 12种排列方式,不是24种

一倍的差距,我TM。。。
而且12种排列可能,12行代码直接列举出来就行了,干嘛要费劲写个全排列啊ค(TㅅT)

然后又发现更好的写法,穷举两位数相乘,再排序判断结果满不满足。。。效率比我这个高多了。参考:java编程——吸血鬼数字(四位)

再后来又看到把效率提高数倍的最佳,经过数学分析的结果,可怕ค(TㅅT) 9的倍数
参考:JAVA实现的吸血鬼数字算法,高效率版本

稍微深入了解了下,类似这种性质的数字叫 傅利曼数