Thinking In Java 裡面吸血鬼數字題

來源:互聯網
上載者:User

標籤:轉換   逆向   網上   數組   from   art   lin   out   改進   

首先解釋一下吸血鬼數字:吸血鬼數字是指位元為偶數的數字,可由一對數字相乘而得到,這對數字各包含乘積的一半位元的數字,以兩個0結尾的數字是不允許的。

 四位元吸血鬼數字樣本:1260=21*60,1827=21*87,2187=27*81……

先列出結果:一共7個:1260=21*60,1395=15*93,1435=41*35,1530=51*30,1827=87*21,2187=27*81,6880=86*80

 

 

方法一:

本方法是《Thinking in Java》的官方答案,由於所處章節很靠前,所以採用的遍曆四位元方法,正向思維,即先有四位元,再拆分,四個數字組合相乘,若乘積與原數相等,則輸出,並計算為一個吸血鬼數字。

  1. public class SearchforVampireThinkinginJava {  
  2.   
  3.     // control/VampireNumbers.java  
  4.     // TIJ4 Chapter Control, Exercise 10, page 154  
  5.     /* A vampire number has an even number of digits and is formed by multiplying a 
  6.     * pair of numbers containing half the number of digits of the result. The 
  7.     * digits are taken from the original number in any order. Pairs of trailing 
  8.     * zeroes are not allowed. Examples include: 1260 = 21 * 60, 1827 = 21 * 87, 
  9.     * 2187 = 27  * 81. Write a program that finds all the 4-digit vampire numbers. 
  10.     * (Suggested by Dan Forhan.) 
  11.     */   
  12. //  本方法是順向思維,即先有四位元,再拆分,四個數字組合相乘,若乘積與原數相等,則輸出,並計算為一個吸血鬼數字。TMJG添加此行並注釋  
  13. //  其實sum的結果為107976次,非常大,演算法效率很低,並且出現了重複(6880 = 86 * 80,6880 = 80 * 86)。TMJG添加此行並注釋  
  14.       
  15.             static int sum=0;//記錄調用判斷的次數,TMJG添加此行並注釋  
  16.             static int a(int i) {  
  17.                 return i/1000;    //求千位元字,下同,TMJG添加此行並注釋  
  18.             }  
  19.             static int b(int i) {  
  20.                 return (i%1000)/100;  
  21.             }  
  22.             static int c(int i) {  
  23.                 return ((i%1000)%100)/10;  
  24.             }  
  25.             static int d(int i) {  
  26.                 return ((i%1000)%100)%10;  
  27.             }  
  28.             static int com(int i, int j) {   //形成10~99的兩位元,TMJG添加此行並注釋  
  29.                 return (i * 10) + j;  
  30.             }  
  31.             static void productTest (int i, int m, int n) {  
  32.                 sum++;  
  33.                 if(m * n == i) System.out.println(i + " = " + m + " * " + n);  
  34.             }     
  35.         public static void main(String[] args) {          
  36.             for(int i = 1001; i < 9999; i++) {             
  37.                 productTest(i, com(a(i), b(i)), com(c(i), d(i)));  
  38.                 productTest(i, com(a(i), b(i)), com(d(i), c(i)));  
  39.                 productTest(i, com(a(i), c(i)), com(b(i), d(i)));  
  40.                 productTest(i, com(a(i), c(i)), com(d(i), b(i)));  
  41.                 productTest(i, com(a(i), d(i)), com(b(i), c(i)));  
  42.                 productTest(i, com(a(i), d(i)), com(c(i), b(i)));  
  43.                 productTest(i, com(b(i), a(i)), com(c(i), d(i)));  
  44.                 productTest(i, com(b(i), a(i)), com(d(i), c(i)));  
  45.                 productTest(i, com(b(i), c(i)), com(d(i), a(i)));  
  46.                 productTest(i, com(b(i), d(i)), com(c(i), a(i)));  
  47.                 productTest(i, com(c(i), a(i)), com(d(i), b(i)));  
  48.                 productTest(i, com(c(i), b(i)), com(d(i), a(i)));  
  49.             }     
  50.             System.out.println("總共調用判斷的次數為:"+sum);//TMJG添加此行並注釋  
  51.         }   
  52. }  

 

 

方法二:

本方法是對方法一的改進,跳過了一些數字(如1100這樣末尾兩個0的,如1010、1001這樣明顯不可能是吸血鬼數位數字),並且避免了出現重複的可能性,但是效率仍然很低,需要判斷104942次。

public class SearchforVampireNumbersLJ {
public static int count = 0;// 記錄一共有多少個吸血鬼數字
public static int k=0;//記錄調用判斷多少次
public static void main(String[] args) {
for (int i = 1001; i < 10000; i++) {
// 如果數字是像1100這種末尾至少有2個0的,則跳過
if (i % 100 == 0) {
continue;
}
// 獲得數字四個數值位上的數字,這裡我們假定四位元表示為abcd
int a = i / 1000;
int b = (i - a * 1000) / 100;
int c = (i - a * 1000 - b * 100) / 10;
int d = i - a * 1000 - b * 100 - c * 10;
// 判斷四個位置上是否有兩個0存在的情況,如1010,並跳過這些數,由於千位不可能為0,因此只需要判斷另外三位是否有2個0的情況
// 當3個數中有2個0時,必然存在“3個數之和等於其中某一個數”,以此作為判斷依據,而後兩位為0的也已經排除,其實只需要判斷如1001,和1010這種情況即可
if (b + c + d == c || b + c + d == d) {
continue;
}
// 排除掉各種情況後,可以開始真正的吸血鬼數字篩選了
// 那麼一共有12種情況:abcd,abdc,acbd,acdb,adbc,adcb,bacd,badc,bcda,bdca,cadb,cbda
if (search(i, a, b, c, d)) {
} else if (search(i, a, b, d, c)) {
} else if (search(i, a, c, b, d)) {
} else if (search(i, a, c, d, b)) {
} else if (search(i, a, d, b, c)) {
} else if (search(i, a, d, c, b)) {
} else if (search(i, b, a, c, d)) {
} else if (search(i, b, a, d, c)) {
} else if (search(i, b, c, d, a)) {
} else if (search(i, b, d, c, a)) {
} else if (search(i, c, a, d, b)) {
} else if (search(i, c, b, d, a)) {
}
}
System.out.println("四位元的吸血鬼數字一共有" + count + "個。");
System.out.println("一共調用判斷次數為" + k);
}

//判斷是否滿足條件
static boolean search(int i, int a, int b, int c, int d) {
k++;
if ((a * 10 + b) * (c * 10 + d) == i) {
searchfor(i,a,b,c,d);//如果滿足條件,則列印結果
return true;
}else{
return false;
}
}

//滿足條件即列印,並且統計個數
static void searchfor(int i, int a, int b, int c, int d) {
count++;
System.out.println(i + "=" + (a * 10 + b) + "*" + (c * 10 + d));
}
}

 

方法三:

以下是網上找的代碼,該演算法採用逆向思維,4位元字的吸血鬼數字只能拆分成兩個2位元,因此遍曆所有兩個兩位元相乘的情況,除去不符合的情況不用判斷,其他挨個判斷即可。

public class SearchforVampireFromInternet {
/**
* 代碼來自網路,略作修改並添加了注釋
* 該演算法只需要執行3721次
*/
public static void main(String[] args) {
String[] targetNum = null;
String[] gunNum=null; //目標數字和槍數字(即對比數字)
int sum = 0; //吸血鬼數位總個數
int count=0; //有效判斷次數,那些乘積不是4位元的就排除了
for (int i = 10; i < 100; i++) {
for (int j = i+1; j < 100; j++) { //沒有哪個兩位元滿足ab*ab=abab(不信可以編程驗證),所以這裡j從i+1開始就可以了
int i_target = i * j;
if (i_target < 1000 || i_target > 9999)
continue; // 積不是4位元則跳過
count++;
targetNum = String.valueOf(i_target).split(""); //將其轉換為一個字串數組
gunNum = (String.valueOf(i) + String.valueOf(j)).split("");
java.util.Arrays.sort(targetNum); //升序排列,因為只有排列了再比較才能保證不遺漏abcd=ba*dc這樣的情況
java.util.Arrays.sort(gunNum);
if (java.util.Arrays.equals(targetNum, gunNum)) {
// 排序後比較,為真則找到一組
sum++;
System.out.println("第" + sum + "個: " + i_target+"="+i + "*" + j);
}
}
}
System.out.println("共進行了"+count+"次判斷,找到" + sum + "個吸血鬼數字。");
}
}

Thinking In Java 裡面吸血鬼數字題

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.