吸血鬼数字 高效算法

提前声明. 此算法来自 【老紫竹】. 
老紫竹CSDN ID:java2000_net 
废话不多说.直接上代码

 

 

[java] view plaincopy
 
  1. package com.javaeye.arrick.util;  
  2. import java.util.Arrays;     
  3. /**   
  4.  * 吸血鬼数字,高效率版本.<br>   
  5.  * 一个4位数字,可以拆分2个2位数数字的乘积,顺序不限。<br>   
  6.  * 比如 1395 =15 * 93   
  7.  *    
  8.  * @author 老紫竹(laozizhu.com)   
  9.  */    
  10. public class VampireNumber {     
  11.   public static void main(String[] arg) {     
  12.     String[] ar_str1, ar_str2;     
  13.     int sum = 0;     
  14.     int from;     
  15.     int to;     
  16.     int i_val;     
  17.     int count = 0;     
  18.     // 双重循环穷举     
  19.     for (int i = 10; i < 100; i++) {     
  20.       // j=i+1避免重复     
  21.       from = Math.max(1000 / i, i + 1); //返回两个int值中较大的一个  
  22.       to = Math.min(10000 / i, 100);   //返回两个int值中较小的一个  
  23.       for (int j = from; j < to; j++) {     
  24.         i_val = i * j;     
  25.         if (i_val % 100 == 0 ||(i_val - i - j) % 9 != 0) {     
  26.           continue;     
  27.         }     
  28.         count++;  
  29.         ar_str1 = String.valueOf(i_val).split("");     
  30.         ar_str2 = (String.valueOf(i) + String.valueOf(j)).split("");     
  31.         Arrays.sort(ar_str1);     
  32.         Arrays.sort(ar_str2);  
  33.         if (Arrays.equals(ar_str1, ar_str2)) {  
  34.            // 排序后比较,为真则找到一组  
  35.            // 返回两个Objects数组彼此相等,返回true  
  36.           sum++;     
  37.           System.out.println("第" + sum + "组: " + i + "*" + j + "=" + i_val);     
  38.         }     
  39.       }     
  40.     }     
  41.     System.out.println("共找到" + sum + "组吸血鬼数");     
  42.     System.out.println(count);     
  43.   }     
  44. }    

 

 

运行结果

 

[java] view plaincopy
 
  1. 1组: 15*93=1395  
  2. 2组: 21*60=1260  
  3. 3组: 21*87=1827  
  4. 4组: 27*81=2187  
  5. 5组: 30*51=1530  
  6. 6组: 35*41=1435  
  7. 7组: 80*86=6880  
  8. 共找到7组吸血鬼数  
  9. 232  

 

 

count 次数只有232.. 已经算是最高效的了. 
而主要的高效代码 只有3行代码

 

 

[java] view plaincopy
 
  1. if (i_val % 100 == 0 ||(i_val - i - j) % 9 != 0) {     
  2.   continue;     
  3. }     

 

 

而已 
i_val % 100 -->都明白什么意思. 
(i_val - i -j) % 9 !=0 --> 也许一时想不明白. 
请看如下逻辑. 你会一目了然 
算法解释: 
假设 
i_val = 1000a + 100b + 10c + d, 
因为满足i_val = x * y, 
则有x = 10a + b, y = 10c + d 
则i_val - x - y = 990a + 99b + 9c = 9 * (110a + 11b + c) 
所以i_val - x - y能被9整除。 
所以满足该条件的数字必定能被9整除,所以可以直接过滤其他数字。 
完毕. 
《Thinking in Java》 (Dan Forhan推荐练习代码)

posted @ 2013-11-15 10:02  FH1004322  阅读(245)  评论(0)    收藏  举报