`
universsky
  • 浏览: 99520 次
文章分类
社区版块
存档分类
最新评论

JAVA算法求水仙花数

 
阅读更多
import java.math.BigInteger;
import java.util.Hashtable;

public class Main {

    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 = SIZE > 9 ? 9 : SIZE;
        for (int i = 0; i <= s; i++) {
//            new Main().test(i, startTime);
            // 启动十个线程同时运算
            final int startValue = i;
            new Thread(new Runnable() {

                public void run() {
                    new Main().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));
    }
} 

分享到:
评论

相关推荐

    java水仙花数算法

    在探讨“Java水仙花数算法”的过程中,我们首先需要理解什么是水仙花数,以及如何用Java编程语言实现其算法。水仙花数(Narcissistic number),也被称为自恋数或阿姆斯特朗数,指的是一个n位数等于它的每个数字的n...

    水仙花数Java程序实现

    ### 水仙花数Java程序实现 #### 知识点概述 本篇文章将深入探讨如何使用Java编程语言实现寻找“水仙花数”的过程。首先,我们会介绍什么是水仙花数及其特点;随后,详细解析给定Java代码的具体实现方式,并在此...

    七种方法求水仙花数

    下面我们将介绍七种不同的方法来求水仙花数,分别使用OpenMP、MPI、MFC、Java等技术。 OpenMP方法 OpenMP是一种并行编程模型,使用#pragma omp parallel for指令可以将循环并行化。下面是使用OpenMP求水仙花数的...

    Java学习~水仙花数

    本Java学习资源主要围绕如何使用Java编程语言来识别和生成水仙花数。 首先,理解水仙花数的概念是关键。在n进制系统中,一个d位的水仙花数由n个不同的数字组成,且满足以下条件: \[ \sum_{i=0}^{d-1} n^{i} \cdot...

    java编写水仙花数

    在编程领域,水仙花数是一个有趣的数学概念,它与计算机科学中的算法和数值处理紧密相关。水仙花数,也被称为自恋数或阿波罗尼奥斯数,是指一个三位数,其每一位数字的立方和等于这个数本身。这个概念可以作为编程...

    求水仙花数

    在编程中,我们可以创建一个算法来找出所有的水仙花数。下面是一个使用Java实现的示例: ```java public class ShuiXian { public static void main(String[] args) { int start = 100; // 三位数的起始值 int ...

    java 水仙花数代码实现

    在Java中实现水仙花数的算法,我们需要了解基本的数学概念和Java编程技巧。以下是一个详细的步骤和代码实现。 首先,我们要明确算法的核心思想: 1. 遍历100到999(或任意指定的三位数范围)的所有数字。 2. 对于每...

    java 打印出所有的水仙花数

    ### Java打印所有水仙花数的知识点解析 #### 一、水仙花数定义与特点 水仙花数(Narcissistic number)是指一个 n 位正整数(n≥3),它的每个位上的数字的n次幂之和等于它本身。例如,153是一个3位数,1^3 + 5^3 +...

    java求21位水仙花数

    根据给定文件的信息,我们可以分析出这是一个用于寻找21位水仙花数的Java程序。在深入探讨之前,我们先来定义一下什么是“水仙花数”:一个n位数称为水仙花数,如果该数字等于其各位数字分别被n次方后之和。 ### 1....

    21位水仙花数JAVA代码

    根据给定的信息,本文将详细解析“21位水仙花数JAVA代码”的知识点,包括其定义、实现原理以及代码解读。 ### 一、水仙花数简介 水仙花数是一个n位正整数(n≥3),它的每个位上的数字的n次幂之和等于它本身。例如...

    java作业:水仙花数进阶.zip

    在Java编程领域,"水仙花数"是一个经典的算法题目,它涉及到数字的位值操作和数学知识。水仙花数是指一个三位数,它的每一位数的立方和等于它本身,例如153就是一个水仙花数,因为1^3 + 5^3 + 3^3 = 153。这个作业的...

    Java三种求水仙花数的方法

    "Java三种求水仙花数的方法" 水仙花数是一种特殊的三位数,它的各位数字的立方和等于这个三位数本身。例如,370=3^3+7^3+0^3,371=3^3+7^3+1^3。水仙花数有很多实际应用,如数据压缩、加密算法等。 Java语言提供了...

    java 求水仙花 和猴子选大王

    Java编程语言在处理各种算法和逻辑问题时展现出了强大的能力,比如在本题中提到的“求水仙花数”和“猴子选大王”的问题。让我们分别详细探讨这两个概念。 首先,水仙花数(Narcissistic Number)是指一个n位数,它...

    java小算法 逢七过 水仙花数 逆序数值.md

    有关于逢七过 水仙花数 逆序数值的算法详解以及用Java所编写的代码

    JAVA算法编程题目及答案.doc

    该题目要求学习者编写一个JAVA程序来打印出所有的水仙花数,所谓水仙花数是指一个三位数,其各位数字立方和等于该数本身。该题目旨在考察学习者对水仙花数的理解和编程能力。 程序 4:将一个正整数分解质因数 第四...

    福建师大Java作业1

    ### 题目三:求某长度水仙花数 水仙花数是指一个三位数,其每一位数字的立方和等于这个数本身。例如,153就是一个水仙花数,因为1^3 + 5^3 + 3^3 = 153。解决这个问题,我们可以遍历100到999之间的所有数字,检查...

    java水仙花数实验报告.docx

    在 Java 中,我们可以设计一个简单的算法来找出一定范围内的所有水仙花数。算法的核心是一个循环,它遍历指定范围内的所有数字,并对每个数字应用一个条件检查函数。以下是一种实现方式: ```java public class ...

    Java求10到100000之间的水仙花数算法示例

    Java求10到100000之间的水仙花数算法示例 Java是世界上最流行的编程语言之一,广泛应用于移动应用、Web应用、桌面应用等多个领域。水仙花数是数学中的一种特殊数字,它的每个位上的数字的n次幂之和等于它本身。今天...

    Eclipse实现水仙花

    在本示例中,我们探讨的是如何使用Java编程语言在Eclipse集成开发环境中实现一个计算水仙花数的简单程序。 1. **Eclipse IDE简介**: Eclipse是一款流行的、免费的开源Java集成开发环境(IDE),广泛用于Java应用...

    java水仙花数原理和详解

    以下是对Java实现水仙花数的详细解释: 首先,我们从给出的代码开始分析: ```java 1 public class Shuixianhua { // 类定义,Shuixianhua代表水仙花类 2 public static void main(String[] args) { // 主方法,...

Global site tag (gtag.js) - Google Analytics