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

关于吸血鬼数字,网上有很多的版本,也有最佳实现方式。最近看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实现的吸血鬼数字算法,高效率版本

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值