首页 > 代码库 > Java 找出四位数的全部吸血鬼数字 基础代码实例
Java 找出四位数的全部吸血鬼数字 基础代码实例
/**
* 找出四位数的全部吸血鬼数字
* 吸血鬼数字是指位数为偶数的数字,能够由一对数字相乘而得到,而这对数字各包括乘积的一半位数的数字,当中从最初的数字中选取的数字能够随意排序.
* 以两个0结尾的数字是不同意的。
* 比例如以下列数字都是吸血鬼数字
1260=21*60
1827=21*87
2187=27*81
...
* 比較笨的低效率的做法: 遍历全部四位数, 每生成一个四位数的时候,
* 在双重循环遍历两位数,在两位数的内层循环中推断是否与最外层循环的四位数相等。 假设相等把这些数字都存放到数组,进行排序后比較
* 两组数字,假设相等那么输出这个数就是要找的数字;
*/
了解下这个英文參考:吸血鬼数字
An important theoretical result found by Pete Hartley:
If x·y is a vampire number then x·y == x+y (mod 9)
Proof:
Let mod be the binary modulo operator and d(x) the sum of the decimal digits of x.
It is well-known that d(x) mod 9 = x mod 9, for all x.
Assume x·y is a vampire. Then it contains the same digits as x and y, and in particular d(x·y) = d(x)+d(y). This leads to:
(x·y) mod 9 = d(x·y) mod 9 = (d(x)+d(y)) mod 9 = (d(x) mod 9 + d(y) mod 9) mod 9
= (x mod 9 + y mod 9) mod 9 = (x+y) mod 9
The solutions to the congruence are (x mod 9, y mod 9) in {(0,0), (2,2), (3,6), (5,8), (6,3), (8,5)}
Only these cases (6 out of 81) have to be tested in a vampire search based on testing x·y for different values of x and y.
以下五中方法, 当中还是ThinkinJava给出的參考答案效率最高, 其它高效率做法 , 请网友高手大神补充
import java.util.Arrays; public class Demo3 { static int a; //千位 static int b; //百位 static int c; //十位 static int d; //个位 static int a1; //十位 static int b1; //个位 static int c1; //十位 static int d1; //个位 static int sum = 0; //总和 static int sum2 = 0; //两数之积 public static void main(String[] args) { long startTime = System.nanoTime(); method1(); long endTime = System.nanoTime(); System.out.println("method1 :" + (endTime - startTime)); //method1 :185671841 long s = System.nanoTime(); method2(); long d = System.nanoTime(); System.out.println("method2 :" + (d - s)); //method2 :90556063 long s3 = System.nanoTime(); method3(); long d3 = System.nanoTime(); System.out.println("method3 :" + (d3 - s3));//method3 :574735 long s4 = System.nanoTime(); method4(); long d4 = System.nanoTime(); System.out.println("method4 :" + (d4 - s4));//method4 :22733469 long s5 = System.nanoTime(); method5(); long d5 = System.nanoTime(); System.out.println("method5 :" + (d5 - s5));//method4 :19871660 } private static void method5() { new VampireNumbers(); //该方法 有反复数字 } static 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 VampireNumbers() { 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))); } } } private static void method4() { // 改进 for (int i = 11; i < 100; i++) { for (int j = i; j < 100; j++) { int k = i * j; String kStr = Integer.toString(k); String checkStr = Integer.toString(i) + Integer.toString(j); if (kStr.length() != 4) continue; char[] kChar = kStr.toCharArray(); char[] checkChar = checkStr.toCharArray(); Arrays.sort(kChar); Arrays.sort(checkChar); boolean isVampire = Arrays.equals(kChar, checkChar); if (isVampire) { System.out.println(i + " * " + j + " = " + k); } } } } private static void method3() { // 官方參考答案 int[] startDigit = new int[4]; int[] productDigit = new int[4]; for (int num1 = 10; num1 <= 99; num1++) for (int num2 = num1; num2 <= 99; num2++) { // Pete Hartley‘s theoretical result: // If x·y is a vampire number then // x·y == x+y (mod 9) if ((num1 * num2) % 9 != (num1 + num2) % 9) continue; int product = num1 * num2; startDigit[0] = num1 / 10; startDigit[1] = num1 % 10; startDigit[2] = num2 / 10; startDigit[3] = num2 % 10; productDigit[0] = product / 1000; productDigit[1] = (product % 1000) / 100; productDigit[2] = product % 1000 % 100 / 10; productDigit[3] = product % 1000 % 100 % 10; int count = 0; for (int x = 0; x < 4; x++) for (int y = 0; y < 4; y++) { if (productDigit[x] == startDigit[y]) { count++; productDigit[x] = -1; startDigit[y] = -2; if (count == 4) System.out.println(num1 + " * " + num2 + " : " + product); } } } /* * Output: 15 * 93 : 1395 21 * 60 : 1260 21 * 87 : 1827 27 * 81 : * 2187 30 * 51 : 1530 35 * 41 : 1435 80 * 86 : 6880 *///:~ } private static void method2() { // 穷举2 //遍历四位数,排除00 从1001開始 for (int i = 1001; i <= 9999; i++) { //排除00 if (i % 100 != 00) { for (int k = 0; k < 100; k += 10) { if (k != 0) { //10 -99 for (int j2 = 0; j2 <= 9; j2++) { //生成第一个两位数 for (int j = 0; j < 100; j += 10) { for (int j3 = 0; j3 <= 9; j3++) { //生成第二个两位数 //推断两数之积 if ((k + j2) * (j + j3) == i) { if (compare2(i, k / 10, j2, j / 10, j3)) { System.out .println(i + "=" + (k + j2) + "*" + (j + j3)); } } } } } } } } } } public static void method1() { //穷举1 int x = 0, y = 0; for (int i = 1; i <= 9; i++) { a = i * 1000; for (int j = 0; j <= 9; j++) { b = j * 100; for (int j2 = 0; j2 < 10; j2++) { c = j2 * 10; for (int k = 0; k < 10; k++) { d = k; sum = a + b + c + d; //取当中四个数字 中组成两个两位数 ,假设这两个两位数之积 等于 sum ,则输入 这个数 for (int k2 = 1; k2 < 10; k2++) { a1 = k2 * 10; for (int l = 0; l < 10; l++) { if (a1 + b1 > 100) { break; } b1 = l; //得到一个两位数字 for (int l2 = 1; l2 < 10; l2++) { c1 = l2 * 10; for (int m = l; m < 10; m++) { if (c1 + d1 > 100) { break; } d1 = m; //再得到一个两位数字 sum2 = (a1 + b1) * (c1 + d1); //计算来两个两位数字之积,假设等于sum if (sum2 == sum) { //且尾数不能为00 if (c + d != 0) { // 比較这个几个数字 是否一样 if (compare(a, b, c, d, a1, b1, c1, d1)) { System.out.println(sum + "=" + (a1 + b1) + "*" + (c1 + d1)); } } } } } } } } } } } } private static boolean compare2(int i, int j, int j2, int k, int j3) { int a[] = { i % 10, i / 10 % 10, i / 100 % 10, i / 1000 }; int b[] = { j, j2, k, j3 }; Arrays.sort(a); Arrays.sort(b); if (Arrays.equals(a, b)) return true; else return false; } private static boolean compare(int a2, int b2, int c2, int d2, int a12, int b12, int c12, int d12) { int[] a = new int[4]; int[] b = new int[4]; a[0] = a2 / 1000; a[1] = b2 / 100; a[2] = c2 / 10; a[3] = d2; b[0] = a12 / 10; b[1] = b12; b[2] = c12 / 10; b[3] = d12; Arrays.sort(a); Arrays.sort(b); if (Arrays.equals(a, b)) return true; else return false; } } }