簡單了解吸血鬼數(shù)
今天看文檔急膀,突然看到一個奇怪的名字——“吸血鬼數(shù)”钝腺。
大概查了一下,這種數(shù)字有正常的吸血鬼數(shù)耘成,偽吸血鬼數(shù)和質(zhì)吸血鬼數(shù)榔昔。
正常的吸血鬼數(shù)驹闰,有以下特征:
1.位數(shù)為偶數(shù);
2.由兩個數(shù)字相乘得到,并且得到的乘積數(shù)字中,包含這兩個數(shù)字擁有的全部數(shù)字,單個數(shù)字的數(shù)量也是一致的撒会;
3.不以兩個0結(jié)尾嘹朗。
比如:21×60 = 1260,其中乘積1260就是正常的吸血鬼數(shù)诵肛,因為該數(shù)字包含了乘數(shù)21和被乘數(shù)60所擁有的所有數(shù)字屹培。21和60即是該吸血鬼數(shù)的兩個尖牙。
再比如:210×600 = 126000曾掂,因為210和600都以0為個位數(shù)(結(jié)尾)惫谤,所以乘積126000就不是一個吸血鬼數(shù)。
再比如:31×33 = 1023珠洗,因為乘積1023中,擁有乘數(shù)31和被乘數(shù)33沒有的數(shù)字“0”和“2”若专,所以乘積1023也不是一個吸血鬼數(shù)许蓖。
一個吸血鬼數(shù)可以多對尖牙。在四位數(shù)的吸血鬼數(shù)中调衰,有一個數(shù)字125460膊爪,該數(shù)字就很特殊:204×615=246×510=125460。所以204嚎莉、615和246米酬、510都是125460的尖牙。
偽吸血鬼數(shù):和正常的吸血鬼數(shù)唯一不同的就是趋箩,其位數(shù)可以是奇數(shù)赃额。
質(zhì)吸血鬼數(shù):尖牙是質(zhì)因數(shù)(能整除給定正整數(shù)的質(zhì)數(shù))的吸血鬼數(shù),例如117067, 124483, 146137, 371893, 536539叫确。
查找吸血鬼數(shù)
因為有點空余時間跳芳,所以打算用java實現(xiàn)一下正常吸血鬼數(shù)的查找邏輯。
實現(xiàn)時竹勉,遵循的基本查找規(guī)則飞盆,就是正常吸血鬼數(shù)擁有的那3個特征。
查找的實現(xiàn)方式有多種次乓,下面是我比較喜歡的一個實現(xiàn)方式吓歇。
該實現(xiàn)方式可以查找任意指定位數(shù)(位數(shù)必須是偶數(shù))的吸血鬼數(shù)。
小伙伴們可以自己拷貝代碼執(zhí)行一下即可看到輸出結(jié)果票腰。
Java代碼:
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 查找吸血鬼數(shù)字
* 數(shù)字特點:
* 位數(shù)為偶數(shù)
* 由兩個數(shù)字相乘得到,并且得到的乘積數(shù)字中,包含這兩個數(shù)字擁有的全部數(shù)字,單個數(shù)字的數(shù)量也是一致的
* 不已以兩個0結(jié)尾
* @author Alisallon
*/
public class VampireTools {
private static class VampireData {
private int m; // 乘數(shù)
private int n; // 被乘數(shù)
private int v; // 乘積
private VampireData(int m, int n, int v) {
this.m = m;
this.n = n;
this.v = v;
}
}
public static void main(String[] args) {
// 查找4位數(shù)范圍內(nèi)的吸血鬼數(shù)字
System.out.println("查找4位數(shù)范圍內(nèi)的吸血鬼數(shù)字");
findVampireNum(4);
// 查找6位數(shù)范圍內(nèi)的吸血鬼數(shù)字
System.out.println("查找6位數(shù)范圍內(nèi)的吸血鬼數(shù)字");
findVampireNum(6);
// // 查找8位數(shù)范圍內(nèi)的吸血鬼數(shù)字
// System.out.println("查找8位數(shù)范圍內(nèi)的吸血鬼數(shù)字");
// findVampireNum(8);
}
/**
* 查找指定位數(shù)的吸血鬼數(shù)字
* @author Alisallon
*
* @param digits int 指定位數(shù)
*/
private static void findVampireNum(int digits) {
if (digits < 4) {
System.out.println("查找的位數(shù)至少是4位");
return;
}
if (digits % 2 != 0) {
System.out.println("查找的位數(shù)必須數(shù)偶數(shù)");
return;
}
// 計算開始查找的位置
int startNum = Double.valueOf(Math.pow(10, digits / 2 - 1)).intValue();
// 計算結(jié)束查找的位置
int endNum = Double.valueOf(Math.pow(10, digits / 2)).intValue() - 1;
// 查找開始時間
long startTime = System.currentTimeMillis();
// 存放滿足條件的吸血鬼數(shù)字對象,注意防止出現(xiàn)重復組合,比如21 * 60 和 60 * 21
Map<String, VampireData> vampireMap = new HashMap<>();
for (int m = startNum; m < endNum; m++) {
for (int n = startNum; n < endNum; n++) {
// 排除長度不相等的兩個數(shù)字
if (String.valueOf(m).length() != String.valueOf(n).length()) {
continue;
}
int value = m * n;
// 排除小于最小乘積和大于最大乘積的乘積
if (value < startNum * endNum || value > startNum * endNum * 10 - 1) {
continue;
}
// 去除以兩個0結(jié)尾的乘積
if (value % 100 == 0) {
continue;
}
// 檢測指定兩個數(shù)字的乘積是否是吸血鬼數(shù)字
checkNumIsVampireNum(m, n, vampireMap);
}
}
// 查找結(jié)束時間
long endTime = System.currentTimeMillis();
System.out.println("吸血鬼數(shù)字查找時間: " + (endTime - startTime) + "ms");
Set<Map.Entry<String, VampireData>> entrySet = vampireMap.entrySet();
// 存放吸血鬼數(shù)字對象,用于排序顯示
List<VampireData> valueList = new ArrayList<>();
// 保存非重復的吸血鬼數(shù)字
Set<Integer> valueSet = new HashSet<>();
for (Map.Entry<String, VampireData> entry : entrySet) {
valueList.add(entry.getValue());
valueSet.add(entry.getValue().v);
}
System.out.println("吸血鬼數(shù)字數(shù)量: " + vampireMap.size() + " 其中重復的數(shù)量:" + (vampireMap.size() - valueSet.size()));
// 對valueList降序排序
valueList.sort(Comparator.comparingInt(o -> o.v));
for (VampireData vampireData : valueList) {
// 控制臺輸出結(jié)果
System.out.println(vampireData.m + " * " + vampireData.n + " = " + vampireData.v);
}
}
/**
* 檢測指定兩個數(shù)字的乘積是否是吸血鬼數(shù)字
* @author Alisallon
*
* @param m int
* @param n int
* @param vampireMap Map<String, VampireData> 存放滿足條件的吸血鬼數(shù)字對象,注意防止出現(xiàn)重復組合,比如21 * 60 和 60 * 21
*/
private static void checkNumIsVampireNum(int m, int n, Map<String, VampireData> vampireMap) {
char[] charArray = concat(String.valueOf(m).toCharArray(), String.valueOf(n).toCharArray());
char[] valueStrArray = String.valueOf(m * n).toCharArray();
for (char aCharArray : charArray) {
// 乘積必須包含兩個乘數(shù)擁有的所有數(shù)字
// 檢測乘積字符數(shù)組中指定的字符,并替換為其他非數(shù)組字符
if (!checkAndReplaceChar(aCharArray, valueStrArray)) {
return;
}
}
// 判斷乘積字符數(shù)組中,是否還有數(shù)字,如果還有數(shù)字,則表示m * n的值,不是吸血鬼數(shù)字
String valueStr = String.valueOf(valueStrArray);
Pattern p = Pattern.compile(".*\\d+.*");
Matcher matcher = p.matcher(valueStr);
if (!matcher.matches()) {
// 乘積字符數(shù)組中沒有數(shù)字了,全部被替換為其他非數(shù)組字符,m * n的值是吸血鬼數(shù)字
// 比較大小,是為了防止出現(xiàn)重復組合,比如21 * 60 和 60 * 21, 在這里統(tǒng)一成 21 * 60
if (m < n) {
vampireMap.put(m + " * " + n, new VampireData(m, n, m * n));
} else {
vampireMap.put(n + " * " + m, new VampireData(n, m, m * n));
}
}
}
/**
* 檢測并替換乘積字符數(shù)組中指定的字符
* @author Alisallon
*
* @param c char 指定的字符
* @param valueCharArray char[] 乘積字符數(shù)組
* @return boolean 檢測并替換結(jié)果
*/
private static boolean checkAndReplaceChar(char c, char[] valueCharArray) {
for (int index = 0; index < valueCharArray.length; index++) {
if (valueCharArray[index] == c) {
// 替換該位置字符為x,也可以是其他非數(shù)字字符
valueCharArray[index] = 'x';
return true;
}
}
return false;
}
/**
* 合并兩個char數(shù)組
* @author Alisallon
*
* @param first char[]
* @param second char[]
* @return char[] 合并后的char數(shù)組
*/
private static char[] concat(char[] first, char[] second) {
char[] result = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, result, first.length, second.length);
return result;
}
}
命令行輸出(注意125460這個數(shù)字):
查找4位數(shù)范圍內(nèi)的吸血鬼數(shù)字
吸血鬼數(shù)字查找時間: 6ms
吸血鬼數(shù)字數(shù)量: 7 其中重復的數(shù)量:0
21 * 60 = 1260
15 * 93 = 1395
35 * 41 = 1435
30 * 51 = 1530
21 * 87 = 1827
27 * 81 = 2187
80 * 86 = 6880
查找6位數(shù)范圍內(nèi)的吸血鬼數(shù)字
吸血鬼數(shù)字查找時間: 148ms
吸血鬼數(shù)字數(shù)量: 142 其中重復的數(shù)量:1
201 * 510 = 102510
260 * 401 = 104260
210 * 501 = 105210
204 * 516 = 105264
150 * 705 = 105750
135 * 801 = 108135
158 * 701 = 110758
152 * 761 = 115672
161 * 725 = 116725
167 * 701 = 117067
141 * 840 = 118440
231 * 534 = 123354
281 * 443 = 124483
152 * 824 = 125248
231 * 543 = 125433
246 * 510 = 125460
204 * 615 = 125460
201 * 627 = 126027
261 * 486 = 126846
140 * 926 = 129640
179 * 725 = 129775
311 * 422 = 131242
323 * 410 = 132430
315 * 423 = 133245
317 * 425 = 134725
231 * 588 = 135828
351 * 387 = 135837
215 * 635 = 136525
146 * 938 = 136948
350 * 401 = 140350
351 * 414 = 145314
317 * 461 = 146137
156 * 942 = 146952
251 * 608 = 152608
261 * 585 = 152685
356 * 431 = 153436
240 * 651 = 156240
269 * 581 = 156289
165 * 951 = 156915
176 * 926 = 162976
396 * 414 = 163944
221 * 782 = 172822
231 * 750 = 173250
371 * 470 = 174370
231 * 759 = 175329
225 * 801 = 180225
201 * 897 = 180297
225 * 810 = 182250
281 * 650 = 182650
216 * 864 = 186624
210 * 906 = 190260
210 * 915 = 192150
327 * 591 = 193257
395 * 491 = 193945
275 * 719 = 197725
252 * 801 = 201852
255 * 807 = 205785
216 * 981 = 211896
341 * 626 = 213466
251 * 860 = 215860
323 * 671 = 216733
321 * 678 = 217638
248 * 881 = 218488
269 * 842 = 226498
276 * 822 = 226872
248 * 926 = 229648
338 * 692 = 233896
461 * 524 = 241564
422 * 581 = 245182
296 * 851 = 251896
350 * 725 = 253750
470 * 542 = 254740
323 * 806 = 260338
284 * 926 = 262984
437 * 602 = 263074
489 * 582 = 284598
420 * 678 = 284760
468 * 612 = 286416
320 * 926 = 296320
431 * 707 = 304717
431 * 725 = 312475
321 * 975 = 312975
534 * 591 = 315594
351 * 909 = 319059
336 * 951 = 319536
524 * 623 = 326452
342 * 963 = 329346
356 * 926 = 329656
530 * 635 = 336550
360 * 936 = 336960
392 * 863 = 338296
533 * 641 = 341653
366 * 948 = 346968
369 * 981 = 361989
392 * 926 = 362992
533 * 686 = 365638
585 * 630 = 368550
381 * 969 = 369189
383 * 971 = 371893
431 * 878 = 378418
435 * 870 = 378450
432 * 891 = 384912
465 * 831 = 386415
593 * 662 = 392566
446 * 908 = 404968
491 * 845 = 414895
641 * 650 = 416650
468 * 891 = 416988
482 * 890 = 428980
464 * 926 = 429664
476 * 941 = 447916
540 * 846 = 456840
546 * 840 = 458640
570 * 834 = 475380
624 * 780 = 486720
549 * 891 = 489159
545 * 899 = 489955
590 * 845 = 498550
681 * 759 = 516879
572 * 926 = 529672
563 * 953 = 536539
630 * 855 = 538650
588 * 951 = 559188
657 * 864 = 567648
650 * 875 = 568750
680 * 926 = 629680
650 * 983 = 638950
720 * 936 = 673920
788 * 926 = 729688
765 * 963 = 736695
843 * 876 = 738468
776 * 992 = 769792
875 * 902 = 789250
825 * 957 = 789525
855 * 927 = 792585
807 * 984 = 794088
891 * 909 = 809919
894 * 906 = 809964
858 * 951 = 815958
896 * 926 = 829696
891 * 945 = 841995
953 * 986 = 939658