/**
*
* @author 东海陈光剑 2013-4-26下午12:55:48
* flower_numbers.java
* chenguangjian iSword
* Email:universsky@126.com
* Blog: http://blog.sina.com.cn/universsky11/
* http://blog.csdn.com/universsky
* http://blog.163.com/universsky@126/
*/
package iSword;
/**
*
* @author 东海陈光剑 2013-4-26下午12:55:48
* flower_numbers.java
* chenguangjian iSword
* Email:universsky@126.com
* Blog: http://blog.sina.com.cn/universsky11/
* http://blog.csdn.com/universsky
* http://blog.163.com/universsky@126/
*/
import java.math.BigInteger;
import java.util.Hashtable;
public class flower_numbers {
private static final int SIZE = 21;
private int[] countArray = new int[10]; // 个数列表
private int[] countSumArray = new int[10]; // 个数总数
private BigInteger[] sumArray = new BigInteger[10];// 值总数
private int offset = 0;// 浮标
/**
* 设置当前浮标对应的个数,个数的总数,值总数
*
* @param num
* 个数
*/
private void setValue(int num) {
countArray[offset] = num;
if (offset == 0) {
countSumArray[offset] = num;
sumArray[offset] = p(9 - offset).multiply(n(num));
} else {
countSumArray[offset] = countSumArray[offset - 1] + num;
sumArray[offset] = sumArray[offset - 1].add(p(9 - offset).multiply(n(num)));
}
}
/**
* 检验当前数据是否匹配
*
* @return
*/
private boolean checkPersentArray() {
BigInteger minVal = sumArray[offset];// 当前已存在值
BigInteger maxVal = sumArray[offset].add(p(9 - offset).multiply(n(SIZE - countSumArray[offset])));// 当前已存在值+可能存在的最大值
// 最小值匹配
if (minVal.compareTo(MAX) > 0) {
return false;
}
// 最大值匹配
if (maxVal.compareTo(MIN) < 0) {
return false;
}
String minStr = minVal.compareTo(MIN) > 0 ? minVal.toString() : MIN.toString();
String maxStr = maxVal.compareTo(MAX) < 0 ? maxVal.toString() : MAX.toString();
// 找到最小值与最大值间首部相同的部分
int[] sameCountArray = new int[10];
for (int i = 0; i < SIZE; i++) {
char c;
if ((c = minStr.charAt(i)) == maxStr.charAt(i)) {
sameCountArray[c - '0'] = sameCountArray[c - '0'] + 1;
} else {
break;
}
}
// 判断如果相同部分有数据大于现在已记录的位数,返回false
for (int i = 0; i <= offset; i++) {
if (countArray[i] < sameCountArray[9 - i]) {
return false;
}
}
// 如果当前值的总数为SIZE位,那么判断该值是不是需要查找的值
if (countSumArray[offset] == SIZE) {
String sumStr = sumArray[offset].toString();
BigInteger sum = ZERO;
for (int i = 0; i < sumStr.length(); i++) {
sum = sum.add(p(sumStr.charAt(i) - '0'));
}
return sum.compareTo(sumArray[offset]) == 0;
}
return true;
}
/**
* 退出循环,打印
*
* @return
*/
private void success() {
System.out.println("find a match number:" + sumArray[offset]);
}
/**
* 将浮标指向下一位数
*
* @return
*/
private void next() {
offset++;
setValue(SIZE - countSumArray[offset - 1]);
}
/**
*
* 回退浮标,找到最近的浮标,并减一
*
* @return
*/
private boolean back() {
// 回退浮标,找到最近的浮标,并减一
if (countArray[offset] == 0) {
while (countArray[offset] == 0) {
if (offset > 0) {
offset--;
} else {
return true;
}
}
}
if (offset > 0) {
setValue(countArray[offset] - 1);
return false;
} else {
return true;
}
}
/**
* 测试程序
*
* @param startValue
* 测试匹配数中包含9的个数
* @param startTime
* 程序启动时间
*/
private void test(int startValue, long startTime) {
// 设置9的个数
offset = 0;
setValue(startValue);
while (true) {
if (checkPersentArray()) {// 检查当前提交数据是否匹配
// 匹配且总数正好为SIZE的位数,那么就是求解的值
if (countSumArray[offset] == SIZE) {
success();
}
// 总数不为SIZE,且当前值不在第10位(即不等于0)
if (offset != 9) {
next();
continue;
}
// 总数不为SIZE,且当前值在第10位。
if (back()) {
break;
}
} else {
if (back()) {
break;
}
}
}
System.out.println(Thread.currentThread() + " End,Spend time " + (System.currentTimeMillis() - startTime) / 1000 + "s");
}
/**
* 主函数
*/
public static void main(String[] args) {
final long startTime = System.currentTimeMillis();
int s = MAX.divide(p(9)).intValue();
for (int i = 0; i <= s; i++) {
// new Main().test(i, startTime);
// 启动十个线程同时运算
final int startValue = i;
new Thread(new Runnable() {
public void run() {
new flower_numbers().test(startValue, startTime);
}
}).start();
}
}
private static final BigInteger ZERO = new BigInteger("0");
private static final BigInteger MIN;
private static final BigInteger MAX;
/**
* 0-SIZE间的BigInteger
*/
private static final BigInteger n(int i) {
return (BigInteger) ht.get("n_" + i);
}
/**
* 0-9的次方的BigInteger
*/
private static final BigInteger p(int i) {
return (BigInteger) ht.get("p_" + i);
}
/**
* 用于缓存BigInteger数据,并初始化0-SIZE间的BigInteger和0-9的次方的BigInteger
*/
private static Hashtable<String, Object> ht = new Hashtable<String, Object>();
static {
int s = SIZE < 10 ? 10 : SIZE;
for (int i = 0; i <= s; i++) {
ht.put("n_" + i, new BigInteger(String.valueOf(i)));
}
for (int i = 0; i <= 10; i++) {
ht.put("p_" + i, new BigInteger(String.valueOf(i)).pow(SIZE));
}
MIN = n(10).pow(SIZE - 1);
MAX = n(10).pow(SIZE).subtract(n(1));
}
}
分享到:
相关推荐
《少儿编程Scratch项目:水仙花数的算法探索》 在编程的世界里,算法是解决问题的核心工具,而“水仙花数”是初学者接触算法的一个有趣实例。本项目针对少儿编程爱好者,通过Scratch这个图形化编程平台,让孩子们在...
在探讨“判断水仙花数的算法”这一主题时,我们首先需要理解何为水仙花数(Narcissistic number)。水仙花数是指一个n位正整数(n≥3),它的每个位上的数字的n次幂之和等于它本身。例如,153是一个三位数,而1^3 + ...
下面是一个简单的 C# 算法实例,用于找出100到999之间的所有水仙花数: ```csharp using System; class Program { static void Main() { for (int i = 100; i ; i++) { if (IsDaffodil(i)) { Console....
水仙花数是一种特殊的三位数,其每个位上的数字的立方和等于该数本身。例如,153是一个水仙花数,因为1的立方是1,5的立方是125,3的立方是27,而1125+27=153。在编程中,我们可以编写一个程序来查找指定范围内的...
在C#中,实现寻找水仙花数的算法是一项基础练习,它可以帮助我们理解控制流、数学运算以及循环结构等基本概念。 首先,我们需要创建一个方法来检查一个数字是否为水仙花数。这个方法通常接收一个整数作为参数,然后...
水仙花数的算法实现主要涉及以下几个步骤: 1. **定义范围**:由于水仙花数是三位数,因此我们的检查范围应从100到999。这是所有可能的三位数。 2. **循环遍历**:对范围内的每个数进行遍历。可以用for循环来实现...
在探讨“Java水仙花数算法”的过程中,我们首先需要理解什么是水仙花数,以及如何用Java编程语言实现其算法。水仙花数(Narcissistic number),也被称为自恋数或阿姆斯特朗数,指的是一个n位数等于它的每个数字的n...
3--[scratch算法练习-水仙花数].zip源码scratch2.0 3.0编程项目源文件源码案例素材源代码3--[scratch算法练习-水仙花数].zip源码scratch2.0 3.0编程项目源文件源码案例素材源代码3--[scratch算法练习-水仙花数].zip...
首先,我们来看第一种算法,即输入一个数判断它是否为水仙花数。这个算法的基本思路是将输入的三位数分解为百位、十位和个位,然后分别计算它们的立方并求和。如果这个和等于原始数字,那么它就是水仙花数。以下是一...
### 水仙花数Java程序实现 #### 知识点概述 本篇文章将深入探讨如何使用Java编程语言实现寻找“水仙花数”的过程。首先,我们会介绍什么是水仙花数及其特点;随后,详细解析给定Java代码的具体实现方式,并在此...
通过以上分析可以看出,这段代码实现了一个高效的算法来寻找21位的水仙花数。通过对每一位数字的逐步构建和验证,有效地减少了搜索空间,从而能够在较短的时间内找出符合条件的数。虽然代码较为复杂,但是通过对关键...
在计算机编程领域,"水仙花数"是一个有趣的概念,主要与数字的算术特性相关。水仙花数,也称为 Narcissistic number,在中国的计算机科学教育中常见于C语言的初学者练习。这个概念源自于这样的数字特性:一个三位数...
**水仙花数**,又称为自恋数或阿姆斯特朗数,是指一个三位数,它的每一位数字的立方和等于它本身。例如,153是一个水仙花数,因为1^3 + 5^3 + 3^3 = 153。 在Python编程中,判断一个数是否为水仙花数可以通过以下...
这表明在寻找21位水仙花数时,需要处理大量的数据计算,因此对于算法效率有一定要求。 ### 三、关键函数与方法解析 #### 1. `multi(char *p, char *q);` 这个函数的功能是将两个字符串表示的大数进行乘法运算,...
七种方法求水仙花数 水仙花数是一种特殊的数字,它的每个数字的立方和等于该数字本身。例如,153就是一个水仙花数,因为1^3 + 5^3 + 3^3 = 153。下面我们将介绍七种不同的方法来求水仙花数,分别使用OpenMP、MPI、...
在编程领域,寻找水仙花数是一种常见的算法练习,用于测试和提升逻辑思维与编程技巧。 给定的代码片段展示了如何用C语言找出100到1000之间的所有水仙花数。这段代码首先定义了四个整型变量i、j、k和n,其中n用于...
水仙花数,又称自恋数或阿姆斯特朗数,是指一个三位数,它的每一位数字的立方和等于它本身。例如,153是一个水仙花数,因为1^3 + 5^3 + 3^3 = 153。在C++编程中,实现寻找水仙花数的程序可以帮助我们理解位操作、...
在MATLAB编程环境中,"水仙花数"(Narcissistic Number)是一个有趣的数学概念。水仙花数是指一个三位数,其各位数字的立方和等于该数本身。例如,153是一个水仙花数,因为1^3 + 5^3 + 3^3 = 153。在本压缩包中,...
在编程领域,水仙花数是一种特殊的三位数(在本...总的来说,这个 Matlab 程序提供了一种有效的算法来查找特定位数的水仙花数,通过理解并应用这些编程技巧,我们可以学习到如何在实际问题中利用数学和编程来解决问题。
在编程领域,"升序排列数组"和"求水仙花数"是两个常见的概念,它们涉及到了数据处理和算法的基础知识。让我们分别探讨这两个主题。 首先,升序排列数组是指将一个数组中的元素按照从小到大的顺序进行排列。这是最...