如何用笨方法找出吸血鬼数字?

慢慢研究Thinking in Java
原题见Thinking in Java第四版 P75 练习10
找出四位数的所有吸血鬼数字
吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘而得到,而这对数字各包含乘积的一半位数的数字,其中从最初的数字中选取的数字可以任意排序.
以两个0结尾的数字是不允许的。←注意这行字
例如下列数字都是吸血鬼数字

1260=21*60
1827=21*87
2187=21*81

注意:以下代码为笨方法来解题
注意:以下代码是以初学者的视角来尽量解决问题,有错误多多包涵
注意:代码设计的东西只包括:for,int[] 无其他高深的知识,应该很轻松就可以看懂
注意:代码中莫名其妙蹦出来的66来自排列组合计算结果,详情请进
https://baike.baidu.com/item/%E6%8E%92%E5%88%97%E7%BB%84%E5%90%88/706498
选择排列查看相关计算方式

  2
C	 =66
  12

计算吸血鬼数的代码如下:
有点多,用了60行代码可以计算得出

package U4;

public class Exam4_8_10 {
    public static void main(String[] args) {

        for (int i=1000; i<10000; i++){

            int[] k = new int[4];
            int[][] l = new int[4][4];
            int[] q = new int[12];
            int count=0;
            int z = i;

            if(z%100 != 0){                     //不允许出现00结尾的数字,出现直接跳过
                for(int j=0; j<4; j++){         //把4位数字拆开
                    k[j] =z%10;
                    z = z/10;
                }

                for (int m=0; m<4; m++){        //把4个数字两两组合并放在一个数组里
                    for (int n=0; n<4; n++){
                        l[m][n] =k[m]*10+k[n];
                    }
                }

                for (int j=0 ;j<4; j++){        //去重,把自己乘自己的部分找出来
                    l[j][j] = 0;
                }

                for (int m=0; m<4; m++){        //然后去掉那部分,形成新数组
                    for (int n=0; n<4; n++){
                        if(l[m][n] != 0){
                            q[count] = l[m][n];
                            count++;
                        }
                    }
                }
                count =66;                      //66的由来是组合C2 12计算得66
                int[] x = new int[count];
                count = 0;
                for (int m=11; m>=0; m--){      //计算拆分两数相乘的结果
                    for (int n=0; n<12; n++){
                        if (m == n){
                            break;
                        }
                        x[count] = q[n]*q[m];
                        count++;
                    }
                }

                for(int m=0; m<count; m++){     //来判断拆分出来的结果再乘回去
                    if(x[m]==i){                //如果乘回去的那么多数字里出现了原拆分数字,则吸血鬼数成立
                        System.out.println("该数字为吸血鬼数:"+x[m]);
                        break;
                    }
                    else {
                        continue;
                    }
                }
            }
            else {                      //这是为了去除吸血鬼数的限制,不能出现00结尾
                continue;
            }
        }
    }
}

这里继续给出判断单个数字是否为吸血鬼数的代码。
该代码i为待判断数字,有需要可以自行修改。
下列代码中包含测试性输出。

package U4;

public class Exam_4_8_10_1 {
    public static void main(String[] args) {
        int i =2187;
        int z = i;
        int[] k = new int[4];
        int[][] l = new int[4][4];
        int[] q = new int[12];
        int count=0;

        System.out.println("输入数字:"+i);

        for(int j=0; j<4; j++){
            k[j] =i%10;
            i = i/10;
        }

        for (int j=0; j<4; j++){
            System.out.println("拆分数字:"+k[j]);
        }

        for (int m=0; m<4; m++){
            for (int n=0; n<4; n++){
                l[m][n] =k[m]*10+k[n];
            }
        }

        for (int j=0 ;j<4; j++){
            l[j][j] = 0;
        }

        for (int m=0; m<4; m++){
            for (int n=0; n<4; n++){
                if(l[m][n] != 0){
                    q[count] = l[m][n];
                    count++;
                }
            }
        }
        count =66;
        int[] x = new int[count];
        count = 0;
        for (int m=11; m>=0; m--){
            for (int n=0; n<12; n++){
                if (m == n){
                    break;
                }
                x[count] = q[n]*q[m];
                count++;
            }
        }
        System.out.println("总数:"+count);

        for(int m=0; m<count; m++){
            if(x[m]==z){
                System.out.println("该数字为吸血鬼数");
                break;
            }
            else {
                continue;
            }
        }
    }
}

这里给出程序2,判断单个数字是否为吸血鬼数的sount:

输入数字:2187
拆分数字:7
拆分数字:8
拆分数字:1
拆分数字:2
总数:66
该数字为吸血鬼数

这里给出程序1,吸血鬼数1000~9999之间的列举结果:

该数字为吸血鬼数:1092
该数字为吸血鬼数:1207
该数字为吸血鬼数:1250
该数字为吸血鬼数:1260
该数字为吸血鬼数:1275
该数字为吸血鬼数:1278
该数字为吸血鬼数:1325
该数字为吸血鬼数:1368
该数字为吸血鬼数:1394
该数字为吸血鬼数:1395
该数字为吸血鬼数:1435
该数字为吸血鬼数:1458
该数字为吸血鬼数:1530
该数字为吸血鬼数:1612
该数字为吸血鬼数:1625
该数字为吸血鬼数:1640
该数字为吸血鬼数:1729
该数字为吸血鬼数:1827
该数字为吸血鬼数:1845
该数字为吸血鬼数:1932
该数字为吸血鬼数:2139
该数字为吸血鬼数:2187
该数字为吸血鬼数:2496
该数字为吸血鬼数:2604
该数字为吸血鬼数:2736
该数字为吸血鬼数:2950
该数字为吸血鬼数:3268
该数字为吸血鬼数:3456
该数字为吸血鬼数:3478
该数字为吸血鬼数:3750
该数字为吸血鬼数:3840
该数字为吸血鬼数:3864
该数字为吸血鬼数:3975
该数字为吸血鬼数:3984
该数字为吸血鬼数:4275
该数字为吸血鬼数:4736
该数字为吸血鬼数:5775
该数字为吸血鬼数:5776
该数字为吸血鬼数:6708
该数字为吸血鬼数:6786
该数字为吸血鬼数:6790
该数字为吸血鬼数:6880
该数字为吸血鬼数:7189
该数字为吸血鬼数:7296
该数字为吸血鬼数:7298
该数字为吸血鬼数:8190
该数字为吸血鬼数:8918

这里也给出Thinking in Java官方给出的答案:

public class VampireNumbers {	
		static int a(int i) {
			return i/1000;
		}
		static int b(int i) {
			return (i%1000)/100;
		}
		static int c(int i) {
			return ((i%1000)%100)/10;
		}
		static int d(int i) {
			return ((i%1000)%100)%10;
		}
		static int com(int i, int j) {
			return (i * 10) + j;
		}
		static void productTest (int i, int m, int n) {
			if(m * n == i) System.out.println(i + " = " + m + " * " + n);
		}	
	public static void main(String[] args) {		
		for(int i = 1001; i < 9999; i++) {			
			productTest(i, com(a(i), b(i)), com(c(i), d(i)));
			productTest(i, com(a(i), b(i)), com(d(i), c(i)));
			productTest(i, com(a(i), c(i)), com(b(i), d(i)));
			productTest(i, com(a(i), c(i)), com(d(i), b(i)));
			productTest(i, com(a(i), d(i)), com(b(i), c(i)));
			productTest(i, com(a(i), d(i)), com(c(i), b(i)));
			productTest(i, com(b(i), a(i)), com(c(i), d(i)));
			productTest(i, com(b(i), a(i)), com(d(i), c(i)));
			productTest(i, com(b(i), c(i)), com(d(i), a(i)));
			productTest(i, com(b(i), d(i)), com(c(i), a(i)));
			productTest(i, com(c(i), a(i)), com(d(i), b(i)));
			productTest(i, com(c(i), b(i)), com(d(i), a(i)));
		}			
	} 
}
//讲道理我没看多懂……不过看这个代码的精简程度,有一种高大上的感觉……

哦对,其中的去重的方法是二维数组,找到重复的改0,
然后判断是否为0之后,再取有用的数据放另外一个数组里,感觉这种方法可行,
免除了单个求费时费力的问题。
其实这两串代码花了我将近两个小时的时间去想
主要的时间耽误在了拆分,枚举上了。

ps:Thinking in Java P75 练习10
pss:今天写这个题目显得很吃力,果然这本书对于新手很不友好。
psss:这个程序写的问题很多,只能做到正常输出正确结果,后续我有时间可以做优化
pssss:也许可以节约不少计算时间(虽然现在也是两三秒内出结果就是)
psssss:Java学习任重而道远。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值