Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 617|回复: 0

[算法学习]找吸血鬼数字

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-10 00:02:19 | 显示全部楼层 |阅读模式
    提前声明. 此算法来自 【老紫竹】.
    老紫竹CSDN ID:java2000_net 主页http://www.laozizhu.com/

    package com.javaeye.arrick.util;
    import java.util.Arrays;   
    /**  
    * 吸血鬼数字,高效率版本.<br>  
    * 一个4位数字,可以拆分2个2位数数字的乘积,顺序不限。<br>  
    * 比如 1395 =15 * 93  
    *   
    * @author 老紫竹(laozizhu.com)  
    */  
    public class VampireNumber {   
      public static void main(String[] arg) {   
        String[] ar_str1, ar_str2;   
        int sum = 0;   
        int from;   
        int to;   
        int i_val;   
        int count = 0;   
        // 双重循环穷举   
        for (int i = 10; i < 100; i++) {   
          // j=i+1避免重复   
          from = Math.max(1000 / i, i + 1); //返回两个int值中较大的一个
          to = Math.min(10000 / i, 100);   //返回两个int值中较小的一个
          for (int j = from; j < to; j++) {   
            i_val = i * j;   
            if (i_val % 100 == 0 ||(i_val - i - j) % 9 != 0) {   
              continue;   
            }   
            count++;
            ar_str1 = String.valueOf(i_val).split("");   
            ar_str2 = (String.valueOf(i) + String.valueOf(j)).split("");   
            Arrays.sort(ar_str1);   
            Arrays.sort(ar_str2);
            if (Arrays.equals(ar_str1, ar_str2)) {
               // 排序后比较,为真则找到一组
               // 返回两个Objects数组彼此相等,返回true
              sum++;   
              System.out.println("第" + sum + "组: " + i + "*" + j + "=" + i_val);   
            }   
          }   
        }   
        System.out.println("共找到" + sum + "组吸血鬼数");   
        System.out.println(count);   
      }   
    }  
                            [/code]
    运行结果
    第1组: 15*93=1395
    第2组: 21*60=1260
    第3组: 21*87=1827
    第4组: 27*81=2187
    第5组: 30*51=1530
    第6组: 35*41=1435
    第7组: 80*86=6880
    共找到7组吸血鬼数
    232
    [/code] count 次数只有232.. 已经算是最高效的了.
    而主要的高效代码 只有3行代码
    if (i_val % 100 == 0 ||(i_val - i - j) % 9 != 0) {   
      continue;   
    }                        [/code] 而已
    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整除,所以可以直接过滤其他数字。
    完毕.

    改成int数组,时间消耗大概只有原来的1/9

    package com.kwzh;
    import java.util.Arrays;
    public class VampireNumber {
            public static void main(String[] args) {
                    float f = System.nanoTime();
                    new VampireNumber().vampireArray();
                    System.out.println("string array: " + (System.nanoTime() - f)
                                    + " nano seconds");
                    f = System.nanoTime();
                    new VampireNumber().vampireArray2();
                    System.out.println("int array: " + (System.nanoTime() - f)
                                    + " nano seconds");
            }
            public void vampireArray() {
                    int small, big, product, floor = 10, ceil = 100;
                    int from, count = 0, sum = 0;
                    String[] ar_str1, ar_str2;
                    for (small = floor; small < ceil; small++) {
                            from = Math.max(1000 / small, small + 1);
                            for (big = from; big < ceil; big++) {
                                    product = small * big;
                                    if (product % 100 == 0 || (product - small - big) % 9 != 0) {
                                            continue;
                                    }
                                    ar_str1 = String.valueOf(product).split("");
                                    ar_str2 = (String.valueOf(small) + String.valueOf(big))
                                                    .split("");
                                    Arrays.sort(ar_str1);
                                    Arrays.sort(ar_str2);
                                    if (Arrays.equals(ar_str1, ar_str2)) {
                                            // 排序后比较,为真则找到一组
                                            // 返回两个Objects数组彼此相等,返回true
                                            sum++;
                                            System.out.println("第" + sum + "组: " + small + "*" + big
                                                            + "=" + product);
                                    }
                                    count++;
                            }
                    }
                    System.out.println(count);
            }
            public void vampireArray2() {
                    int small, big, product, floor = 10, ceil = 100;
                    int from, count = 0, sum = 0;
                    int[] ar_int1 = new int[4], ar_int2 = new int[4];
                    for (small = floor; small < ceil; small++) {
                            from = Math.max(1000 / small, small + 1);
                            for (big = from; big < ceil; big++) {
                                    product = small * big;
                                    if (product % 100 == 0 || (product - small - big) % 9 != 0) {
                                            continue;
                                    }
                                    ar_int1[0] = small / 10;
                                    ar_int1[1] = small % 10;
                                    ar_int1[2] = big / 10;
                                    ar_int1[3] = big % 10;
                                    ar_int2[0] = product / 1000;
                                    product = product % 1000;
                                    ar_int2[1] = product / 100;
                                    product = product % 100;
                                    ar_int2[2] = product / 10;
                                    ar_int2[3] = product % 10;
                                    Arrays.sort(ar_int1);
                                    Arrays.sort(ar_int2);
                                    if (Arrays.equals(ar_int1, ar_int2)) {
                                            sum++;
                                            System.out.println("第" + sum + "组: " + small + "*" + big
                                                            + "=" + product);
                                    }
                                    count++;
                            }
                    }
                    System.out.println(count);
            }
    }
          

                          [/code]
       
         
         
          
          

            
          

            
          
         
       

      


    源码下载:http://file.javaxxz.com/2014/11/10/000218781.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 07:41 , Processed in 0.350889 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表