首页 > 代码库 > 《Thinking in Java》习题——吸血鬼数字
《Thinking in Java》习题——吸血鬼数字
最近在看《Java编程思想》,这本书非常棒,不愧是Java程序员的圣经。看到第四章,后面有道题目很有意思,于是就自己做了做。
1. 我的思路很简单,但是算法效率非常之低。就是把4位数拆成4个数字,比如1260--->1,2,6,0。然后4位数字组合成两个2位数,计算它们
的乘积,相等则就是吸血鬼数字。
1 public class Test2 { 2 /* 3 * 将4位数拆分成4个数 4 * */ 5 public int [] array(int num){ 6 int [] a = new int [4]; 7 int i=0; 8 while(num!=0){ 9 a[i++]=num%10;10 num=num/10;11 }12 return a;13 } 14 /*15 * 将4给数组合成两个数,相乘与4位数比较。相等就是吸血鬼数字16 * 17 * */18 public boolean equal(int num,int [] a){19 for(int i=0;i<4;i++){20 for(int j=0;j<4;j++){21 if(i==j){22 continue;23 }else{24 if(6-i-j==5){//i,j=0或125 if((a[i]*10+a[j])*(a[3]*10+a[2])==num||(a[i]+a[j]*10)*(a[3]*10+a[2])==num){26 return true;27 }28 }29 else if(6-i-j==4){//i,j=0或2 30 if((a[i]*10+a[j])*(a[3]*10+a[1])==num||(a[i]+a[j]*10)*(a[3]*10+a[1])==num){31 return true;32 }33 }34 else if(6-i-j==3&&(i==3||j==3)){ //i,j或0,3 35 if((a[i]*10+a[j])*(a[2]*10+a[1])==num||(a[i]+a[j]*10)*(a[2]*10+a[1])==num){36 return true;37 }38 }39 else if(6-i-j==3&&(i==1||j==1)){//i,j=1或240 if((a[i]*10+a[j])*(a[3]*10+a[0])==num||(a[i]+a[j]*10)*(a[3]*10+a[0])==num){41 return true;42 }43 } 44 else if(6-i-j==2){//i,j=1或3 45 if((a[i]*10+a[j])*(a[2]*10+a[0])==num||(a[i]+a[j]*10)*(a[2]*10+a[0])==num){46 return true;47 }48 }49 else if(6-i-j==1){//i,j=2或3 50 if((a[i]*10+a[j])*(a[1]*10+a[0])==num||(a[i]+a[j]*10)*(a[1]*10+a[0])==num){51 return true;52 }53 }54 }55 }56 }57 return false;58 }59 public static void main(String[] args) {60 Test2 t2 = new Test2();61 for(int i =1001;(i<=9999);i++){62 if(t2.equal(i, t2.array(i))){63 System.out.println(i);64 }65 }66 }67 68 }
运行结果:
结果是对的,但是算法效率太低。将近要循环9000*4*4=14400次。
在网上找了找,有很多高效的算法。贴出来研究一下别人的思路。
2.
1 public class XiXueGui { 2 /** 3 * 吸血鬼数字算法 4 * 如:12*60=1260 5 * YangL. 6 */ 7 public static void main(String[] args) { 8 String[] ar_str1 = null, ar_str2; 9 int sum = 0; 10 int count=0;11 for (int i = 10; i < 100; i++) { 12 for (int j = i + 1; j < 100; j++) { 13 int i_val = i * j; 14 if (i_val < 1000 || i_val > 9999) 15 continue; // 积小于1000或大于9999排除,继续下一轮环 16 count++;17 ar_str1 = String.valueOf(i_val).split(""); 18 ar_str2 = (String.valueOf(i) + String.valueOf(j)).split(""); 19 java.util.Arrays.sort(ar_str1); 20 java.util.Arrays.sort(ar_str2); 21 if (java.util.Arrays.equals(ar_str1, ar_str2)) { 22 // 排序后比较,为真则找到一组 23 sum++; 24 System.out.println("第" + sum + "组: " + i + "*" + j + "=" 25 + i_val); 26 } 27 } 28 } 29 System.out.println("共找到" + sum + "组吸血鬼数"+"\ncount"+count);30 31 } 32 }
这个算法非常棒,基本思路是:4位数字的吸血鬼数字只能拆分成两个2位数。于是就计算两个2位数相乘(11,12行)。用String.valueOf(j)).split("");的方法来把数字转换为字符串,排序,比较4位数的字符串和两个2位数的字符串,若相等,就是吸血鬼数字。把数字的比较,转换为对字符串的比较,非常棒。
这个算法循环了3721次。
运行结果:
3.《Thinking in Java》官方答案
1 public class VampireNumbers { 2 static int a(int i) { 3 return i/1000; 4 } 5 static int b(int i) { 6 return (i%1000)/100; 7 } 8 static int c(int i) { 9 return ((i%1000)%100)/10;10 }11 static int d(int i) {12 return ((i%1000)%100)%10;13 }14 static int com(int i, int j) {15 return (i * 10) + j;16 }17 static void productTest (int i, int m, int n) {18 if(m * n == i) System.out.println(i + " = " + m + " * " + n);19 } 20 public static void main(String[] args) { 21 for(int i = 1001; i < 9999; i++) { 22 productTest(i, com(a(i), b(i)), com(c(i), d(i)));23 productTest(i, com(a(i), b(i)), com(d(i), c(i)));24 productTest(i, com(a(i), c(i)), com(b(i), d(i)));25 productTest(i, com(a(i), c(i)), com(d(i), b(i)));26 productTest(i, com(a(i), d(i)), com(b(i), c(i)));27 productTest(i, com(a(i), d(i)), com(c(i), b(i)));28 productTest(i, com(b(i), a(i)), com(c(i), d(i)));29 productTest(i, com(b(i), a(i)), com(d(i), c(i)));30 productTest(i, com(b(i), c(i)), com(d(i), a(i)));31 productTest(i, com(b(i), d(i)), com(c(i), a(i)));32 productTest(i, com(c(i), a(i)), com(d(i), b(i)));33 productTest(i, com(c(i), b(i)), com(d(i), a(i)));34 } 35 } 36 }
《Thinking in Java》习题——吸血鬼数字
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。