JAVA_吸血鬼数字 多种方法实现
package test4; import java.util.Arrays; /**
* 从TIJ中第4章的练习10看到“吸血鬼数字”,以下几种方法实现以及执行时间对比
* 找出四位数的所有吸血鬼数字
* 吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘而得到,而这对数字各包含乘积的一半位数的数字,
* 其中从最初的数字中选取的数字可以任意排序.
* 以两个0结尾的数字是不允许的。
* 例如下列数字都是吸血鬼数字
* 1260=21*60
* 1827=21*87
* 2187=27*81
*/
public class Test1 { public static void main(String[] args) {
long start = System.nanoTime();
fun1();
long end = System.nanoTime();
System.out.println("方法1所用时间:" + (end - start)+"\n"); start = System.nanoTime();
fun2();
end = System.nanoTime();
System.out.println("方法2所用时间:" + (end - start)+"\n"); start = System.nanoTime();
fun3();
end = System.nanoTime();
System.out.println("方法3所用时间:" + (end - start)+"\n"); start = System.nanoTime();
fun4();
end = System.nanoTime();
System.out.println("方法4所用时间:" + (end - start)+"\n");
} private static void fun1() {
//参考答案
int sum = 0;
int[] startDigit = new int[4];
int[] productDigit = new int[4];
for (int num1 = 10; num1 <= 99; num1++)
for (int num2 = num1; num2 <= 99; num2++) {
// Pete Hartley's theoretical result:
// If x·y is a vampire number then
// x·y == x+y (mod 9)
if ((num1 * num2) % 9 != (num1 + num2) % 9)
continue;
int product = num1 * num2;
startDigit[0] = num1 / 10;
startDigit[1] = num1 % 10;
startDigit[2] = num2 / 10;
startDigit[3] = num2 % 10;
productDigit[0] = product / 1000;
productDigit[1] = (product % 1000) / 100;
productDigit[2] = product % 1000 % 100 / 10;
productDigit[3] = product % 1000 % 100 % 10;
int count = 0;
for (int x = 0; x < 4; x++)
for (int y = 0; y < 4; y++) {
if (productDigit[x] == startDigit[y]) {
count++;
productDigit[x] = -1;
startDigit[y] = -2;
if (count == 4) {
System.out.println("第" + sum + "组: " + num1 + " * " + num2 + " : " + product);
sum++;
}
}
}
}
System.out.println("方法1共找到" + sum + "组吸血鬼数");
} private static void fun2() {
String[] ar_str1, ar_str2;
int sum = 0;
int from;
int to;
int i_val;
for (int i = 10; i < 100; i++) {
from = Math.max(1000 / i, i + 1);
to = Math.min(10000 / i, 100);
// 2个数的乘积是4位数(大于等于1000,小于10000),i确定时,另一个数范围随之确定
for (int j = from; j < to; j++) {
i_val = i * j;
if (i_val % 100 == 0 || (i_val - i - j) % 9 != 0) {
// (i_val - i - j) % 9 != 0 的理解:
// 假设val = 1000a + 100b + 10c + d, 因为满足val = x * y, 则有x =
// 10a + b, y = 10c + d
// 可得val - x - y = 990a + 99b + 9c = 9 * (110a + 11b + c),
// 所以val - x - y能被9整除。
// 满足该条件的数字必定能被9整除,可以直接过滤其他数字。
continue;
}
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)) {
sum++;
System.out.println("第" + sum + "组: " + i + "*" + j + "=" + i_val);
}
}
}
System.out.println("方法2共找到" + sum + "组吸血鬼数");
} private static void fun3() {
int sum = 0;
for (int i = 11; i < 100; i++) {
for (int j = i; j < 100; j++) {
int k = i * j;
// 有另一种变为字符串来操作,比较发现下面的这种方法耗时更少
int[] a = { k / 1000, k / 100 % 10, k / 10 % 100 % 10, k % 1000 % 100 % 10 };
int[] b = { i % 10, i / 10, j % 10, j / 10 };
Arrays.sort(a);
Arrays.sort(b);
if (Arrays.equals(a, b)) {
sum++;
System.out.println("第" + sum + "组: " + i + " * " + j + " = " + k);
}
}
}
System.out.println("方法3共找到" + sum + "组吸血鬼数");
} private static void fun4() {
//逆向思维
String[] targetNum = null;
String[] gunNum = null;
int sum = 0;
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位数则跳过
targetNum = String.valueOf(i_target).split("");
gunNum = (String.valueOf(i) + String.valueOf(j)).split("");
Arrays.sort(targetNum);
Arrays.sort(gunNum);
if (Arrays.equals(targetNum, gunNum)) {
sum++;
System.out.println("第" + sum + "组: " + i_target + "=" + i + "*" + j);
}
}
}
System.out.println("方法4找到" + sum + "个吸血鬼数字。");
}
}
执行结果:
第0组: 15 * 93 : 1395
第1组: 21 * 60 : 1260
第2组: 21 * 87 : 1827
第3组: 27 * 81 : 2187
第4组: 30 * 51 : 1530
第5组: 35 * 41 : 1435
第6组: 80 * 86 : 6880
方法1共找到7组吸血鬼数
方法1所用时间:4880538
第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
方法2共找到7组吸血鬼数
方法2所用时间:43971275 第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
方法3共找到7组吸血鬼数
方法3所用时间:19352070 第1组: 1395=15*93
第2组: 1260=21*60
第3组: 1827=21*87
第4组: 2187=27*81
第5组: 1530=30*51
第6组: 1435=35*41
第7组: 6880=80*86
方法4找到7个吸血鬼数字。
方法4所用时间:125098134
JAVA_吸血鬼数字 多种方法实现的更多相关文章
- Java 吸血鬼数字
非常羞愧(事实上没什么羞愧.水平就这样).搞了半晌才写出来了一个Java 版求四位吸血鬼数字的方法 吸血鬼数字是指位数为偶数的数字.能够由一对数字相乘而得到.而这对数字各包括乘积的一半位数的数字,当中 ...
- str.format() 格式化数字的多种方法
Python2.6 开始,新增了一种格式化字符串的函数 str.format(),它增强了字符串格式化的功能. 基本语法是通过 {} 和 : 来代替以前的 % . format 函数可以接受不限个参数 ...
- Java 找出四位数的全部吸血鬼数字 基础代码实例
/** * 找出四位数的全部吸血鬼数字 * 吸血鬼数字是指位数为偶数的数字,能够由一对数字相乘而得到,而这对数字各包括乘积的一半位数的数字,当中从最初的数字中选取的数字能够随意排序. * 以两个 ...
- Java 找出四位数的所有吸血鬼数字 基础代码实例
/** * 找出四位数的所有吸血鬼数字 * 吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘而得到,而这对数字各包含乘积的一半位数的数字,其中从最初的数字中选取的数字可以任意排序. * 以两个 ...
- 《Thinking in Java》习题——吸血鬼数字
最近在看<Java编程思想>,这本书非常棒,不愧是Java程序员的圣经.看到第四章,后面有道题目很有意思,于是就自己做了做.
- 无线加密的多种方法及其区别(WEP WPA TKIP EAP)
无线加密的多种方法及其区别(WEP WPA TKIP EAP) 无线网络的安全性由认证和加密来保证. 认证允许只有被许可的用户才能连接到无线网络: 加密的目的是提供数据的保密性和完整性(数据在传输过程 ...
- javascript实现保留两位小数的多种方法
第一种方法:javascript实现保留两位小数一位自动补零代码实例:第一种方法介绍一下如何实现对数字保留两位小数效果,如果数字的原本小数位数不到两位,那么缺少的就自动补零,这个也是为了统一的效果,先 ...
- CSS导航菜单水平居中的多种方法
CSS导航菜单水平居中的多种方法 在网页设计中,水平导航菜单使用是十分广泛的,在CSS样式中,我们一般会用Float元素或是「display:inline-block」来解决.而今天主要讲解如何让未知 ...
- 用 Python 排序数据的多种方法
用 Python 排序数据的多种方法 目录 [Python HOWTOs系列]排序 Python 列表有内置就地排序的方法 list.sort(),此外还有一个内置的 sorted() 函数将一个可迭 ...
随机推荐
- Spring表单验证
表单验证 给表单添加验证的步骤如下 1.在 pom.xml 里添加 hibernate-validator 依赖http://hibernate.org/validator/documentation ...
- [Alpha]Scrum Meeting#9
github 本次会议项目由PM召开,时间为4月11日晚上10点30分 时长10分钟 任务表格 人员 昨日工作 下一步工作 木鬼 撰写每日例会报告 撰写每日例会报告撰写并整理任务分配博客 SiMrua ...
- CF1007D. Ants(树链剖分+线段树+2-SAT及前缀优化建图)
题目链接 https://codeforces.com/problemset/problem/1007/D 题解 其实这道题本身还是挺简单的,这里只是记录一下 2-SAT 的前缀优化建图的相关内容. ...
- [转] ELK 之 Logstash
[From] https://blog.csdn.net/iguyue/article/details/77006201 ELK 之 Logstash 简介: ELK 之 LogstashLogsta ...
- C# this关键字(给底层类库扩展成员方法)
本文参考自唔愛吃蘋果的C#原始类型扩展方法—this参数修饰符,并在其基础上做了一些细节上的解释 1.this作为参数关键字的作用 使用this关键字,可以向this关键字后面的类型添加扩展方法,而无 ...
- security和oauth2.0的整合
security和oauth2.0的整合 之前已经介绍过security的相关的介绍,现在所需要做的就是security和oauth2.0的整合,在原有的基础上我们加上一些相关的代码;代码实现如下: ...
- UBUNTU 无法解析域名 解决方法
莫名其妙的,ubuntu 无法访问外网. ping www.taobao.com www.baidu.com 提示无效的主机名 但是ping 外网ip 都是可以PING通的. 所以断定是 dns问题 ...
- Chapter 3. Lexical Structure
/** * Expression = Expression1 [ExpressionRest] * ExpressionRest = [AssignmentOperator Expression1] ...
- 事务操作的统计,TPS的计算,隔离级别的读提交
对于事务操作的统计 因为InnoDB存储引擎是支持事务的,因此对于InnoDB存储引擎的应用,在考虑每秒请求数(Question Per Second,QPS)的同时,也许更应该关注每秒事务处理的能力 ...
- WPF中后台代码停止RepeatBehavior=RepeatBehavior.Forever的办法
1.在使用Begin()方法启动动画的时候,要将isControlable设置成true,就是Begin方法的第二个参数 scanningStoryBoard.Begin(this,true);// ...