问题描述
吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘而得到,而这对数字各包含乘积的一半位数的数字,其中从最初的数字中选取的数字可以任意排序。以两个0结尾的数字是不允许的。
例如下列数字都是吸血鬼数字:
- 1260 = 21 × 60
- 1827 = 21 × 87
- 2187 = 27 × 81
算法实现
优化版本的吸血鬼数字查找器
package cn.peiluming.vampire;
import java.util.*;
/**
* 吸血鬼数字查找器
* 吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘而得到,
* 而这对数字各包含乘积的一半位数的数字,其中从最初的数字中选取的数字可以任意排序。
*
* @author plm
*/
public class VampireNumberFinder {
/**
* 查找指定位数的吸血鬼数字
* @param digitCount 位数(必须为偶数)
* @return 吸血鬼数字列表
*/
public static List<VampireResult> findVampireNumbers(int digitCount) {
if (digitCount % 2 != 0) {
throw new IllegalArgumentException("位数必须为偶数");
}
List<VampireResult> results = new ArrayList<>();
int halfDigit = digitCount / 2;
int minMultiplier = (int) Math.pow(10, halfDigit - 1);
int maxMultiplier = (int) Math.pow(10, halfDigit) - 1;
for (int num1 = minMultiplier; num1 <= maxMultiplier; num1++) {
for (int num2 = num1; num2 <= maxMultiplier; num2++) {
long product = (long) num1 * num2;
// 检查乘积是否符合位数要求
if (product < Math.pow(10, digitCount - 1) || product >= Math.pow(10, digitCount)) {
continue;
}
// 排除以两个0结尾的情况
if (endsWithZeros(num1, num2)) {
continue;
}
// 检查数字是否匹配
if (isVampireNumber(num1, num2, product)) {
results.add(new VampireResult(num1, num2, product));
}
}
}
return results;
}
/**
* 检查两个数的乘积是否为吸血鬼数字
* @param num1 第一个因子
* @param num2 第二个因子
* @param product 乘积
* @return 是否为吸血鬼数字
*/
private static boolean isVampireNumber(int num1, int num2, long product) {
String productStr = String.valueOf(product);
String factorsStr = String.valueOf(num1) + String.valueOf(num2);
char[] productChars = productStr.toCharArray();
char[] factorsChars = factorsStr.toCharArray();
Arrays.sort(productChars);
Arrays.sort(factorsChars);
return Arrays.equals(productChars, factorsChars);
}
/**
* 检查两个数是否都以0结尾(避免无效情况)
* @param num1 第一个数
* @param num2 第二个数
* @return 是否都以0结尾
*/
private static boolean endsWithZeros(int num1, int num2) {
return (num1 % 10 == 0 && num2 % 10 == 0);
}
/**
* 吸血鬼数字结果类
*/
public static class VampireResult {
private final int factor1;
private final int factor2;
private final long product;
public VampireResult(int factor1, int factor2, long product) {
this.factor1 = factor1;
this.factor2 = factor2;
this.product = product;
}
@Override
public String toString() {
return String.format("%d × %d = %d", factor1, factor2, product);
}
// Getters
public int getFactor1() { return factor1; }
public int getFactor2() { return factor2; }
public long getProduct() { return product; }
}
public static void main(String[] args) {
System.out.println("=== 4位吸血鬼数字 ===");
List<VampireResult> fourDigitVampires = findVampireNumbers(4);
for (VampireResult result : fourDigitVampires) {
System.out.println(result);
}
System.out.println("总共找到 " + fourDigitVampires.size() + " 个4位吸血鬼数字\n");
System.out.println("=== 6位吸血鬼数字 ===");
List<VampireResult> sixDigitVampires = findVampireNumbers(6);
for (VampireResult result : sixDigitVampires) {
System.out.println(result);
}
System.out.println("总共找到 " + sixDigitVampires.size() + " 个6位吸血鬼数字");
}
}
经典4位吸血鬼数字查找(简化版)
/**
* 经典4位吸血鬼数字查找器(更简洁的实现)
*/
public class SimpleVampireFinder {
public static void findFourDigitVampireNumbers() {
int count = 0;
for (int i = 10; i < 100; i++) {
for (int j = i; j < 100; j++) {
int product = i * j;
// 检查是否为4位数
if (product < 1000 || product > 9999) {
continue;
}
// 检查是否以两个0结尾
if (i % 10 == 0 && j % 10 == 0) {
continue;
}
// 检查数字组成是否相同
if (hasSameDigits(i, j, product)) {
count++;
System.out.printf("第%d组: %d × %d = %d%n", count, i, j, product);
}
}
}
System.out.println("共找到 " + count + " 个4位吸血鬼数字");
}
/**
* 检查两个因子的数字组合是否与乘积的数字组合相同
*/
private static boolean hasSameDigits(int num1, int num2, int product) {
String combined = String.valueOf(num1) + String.valueOf(num2);
String productStr = String.valueOf(product);
char[] combinedArray = combined.toCharArray();
char[] productArray = productStr.toCharArray();
Arrays.sort(combinedArray);
Arrays.sort(productArray);
return Arrays.equals(combinedArray, productArray);
}
public static void main(String[] args) {
findFourDigitVampireNumbers();
}
}
输出示例
=== 4位吸血鬼数字 ===
15 × 93 = 1395
21 × 60 = 1260
21 × 87 = 1827
27 × 81 = 2187
35 × 41 = 1435
45 × 35 = 1575
...
总共找到 X 个4位吸血鬼数字