题目:
吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘而得到,而这对数字各包含乘积的一半位数的数字,其中从最初的数字中选取的数字可以任意排序。以两个0结尾的数字是不被允许的,例如,下列数字都是“吸血鬼”数字:
1260 = 21 * 60
1827 = 21 * 87
2187 = 27 * 81
写一个程序,找出4位数的所有吸血鬼数字。
下面个算法。是我从网上找到的。我觉得这个算法确实不错。比我写的好多了。
public class XiXieGui {
/**
* 吸血鬼数字算法
* 如:12*60=1260
* YangL.
*/
public static void main(String[] args) {
String[] ar_str1, ar_str2;
int sum = 0;
for (int i = 10; i < 100; i++) {
for (int j = i + 1; j < 100; j++) {
int i_val = i * j;
if (i_val < 1000 || i_val > 9999)
continue; // 积小于1000或大于9999排除,继续下一轮环
ar_str1 = String.valueOf(i_val).split("");
ar_str2 = (String.valueOf(i) + String.valueOf(j)).split("");
java.util.Arrays.sort(ar_str1);
java.util.Arrays.sort(ar_str2);
if (java.util.Arrays.equals(ar_str1, ar_str2)) {
// 排序后比较,为真则找到一组
sum++;
System.out.println("第" + sum + "组: " + i + "*" + j + "="
+ i_val);
}
}
}
System.out.println("共找到" + sum + "组吸血鬼数");
}
}
这个算法应该是比较简单的了。算法中用到String.valueOf(j)).split("");的方法来把数字转换为字符串,以拆分数字的方法用的很巧妙了。把数字的比较,转换为对字符串的比较,实在高明。
下面是我写的代码,虽然不怎么样。还是贴出来让大家看看那吧。如果大家发现有什么地方可以优化。希望大家指出。谢谢。
public class XiXueGui {
public static void main(String[] args) {
char[] c = new char[2];
for (int x = 1000; x < 10000; x++) {
if(x%100==0) continue;//排除尾为俩个00的数字
String str = String.valueOf(x);
all: for (int i = 0; i < str.length(); i++) {
for (int k = i + 1; k < str.length(); k++) {
//第一个数
int num11 = ((str.charAt(i) - '0') * 10)
+ (str.charAt(k) - '0');
//第二个数,在第一个数的基础上进行交换
int num12 = ((str.charAt(k) - '0') * 10)
+ (str.charAt(i) - '0');
//找到另外俩个数字,然后也进行组合
int count = 0;
for (int j = 0; j < str.length(); j++) {
if (j != i && j != k) {
c[count] = str.charAt(j);
count++;
}
}
int num1 = ((c[0] - '0') * 10) + (c[1] - '0');
int num2 = ((c[1] - '0') * 10) + (c[0] - '0');
//判断是否符合条件
if (num11 * num1 == x) {
System.out.println(num11 + "*" + num1 + "=" + x);
break all;
} else if (num11 * num2 == x) {
System.out.println(num11 + "*" + num2 + "=" + x);
break all;
} else if (num12 * num1 == x) {
System.out.println(num12 + "*" + num1 + "=" + x);
break all;
} else if (num12 * num2 == x) {
System.out.println(num12 + "*" + num2 + "=" + x);
break all;
}
}
}
}
}
}
输出效果:
21*60=1260
15*93=1395
41*35=1435
51*30=1530
21*87=1827
27*81=2187
86*80=6880
通过对第一种方法的灵感,我又写出了一种方法。虽然方法一样。让大家见笑了。
public class XiXueGui {
public static void main(String[] args) {
for(int i=10;i<100;i++)
{
for(int j=i+1;j<100;j++)
{
int val=i*j;//俩数相乘的积
String valStr=String.valueOf(val);
if(valStr.length()!=4) continue;//不足四位则进行下一次
String ijStr=String.valueOf(i)+String.valueOf(j);
if(Integer.parseInt(ijStr)%100==0) continue;//如果尾部为俩个0则跳过
//判断俩个字符是否含有相同的字符。
for(int k=0;k<4;k++) valStr=valStr.replaceFirst(ijStr.charAt(k)+"", "");
if(valStr.length()==0)
{
System.out.println(i+"*"+j+"="+String.valueOf(val));
}
}
}
}
}