关于21位内的所有水仙花数求取

废话不多说,直接上代码
package lonton.com;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
*

  • @author Zhou
    /
    public class NarcissisticNumber {
    /

    * 一:总体思路:先求出结果,再根据结果中数值进行比对

    • 1使用递归,求出0~9的n次方
    • 2创建一个map集合,集合中key-value分别为09,09的n次方
    • 3使用递归找到各个数字可能出现的次数,创建一个长度为10的数组,将次数根据下标放进数组
    • 4获取和值,通过数组下标值与map中key值一致获取value值,乘以数组下标所对应的值
    • 5比较结果的长度是否与要求的位数一致,数字个数与数组中存放的次数是否一致.
      * 二:编码步骤
    • 1定义一个list集合存放水仙花数
    • 2定义getNarcissistic方法,将0~9的n次方的值存入map集合中
    • 3.1定义一个方法getTargetNum获取目标(水仙花)
    • 3.2使用递归算法获取各个数字出现的所有可能性,写出结束条件
    • 3.3通过map中的value值与数组中存放相关数字的乘积求出结果
    • 3.4对结果进行判断,是否为水仙花数,结果为肯定时放进list集合中
    • 4利用System.currentTimeMillis()方法获取运算时间.
      */
      // 创建list,用于存放水仙花数
      private static List list = new ArrayList();
      // 所求水仙花的位数
      private static int N;

    public static void main(String[] args) {
    // 设置起始时间
    long start = System.currentTimeMillis();
    for (int n = 3; n <= 21; n++) {
    getNarcissistic(n);
    }
    // 遍历集合,输出水仙花数
    System.out.println(list.toString());
    long end = System.currentTimeMillis();
    Long time = end - start;
    System.out.println(time);
    }

    /**
    *

    • @param n 所求水仙花位数

    */
    private static void getNarcissistic(int n) {
    N = n;
    Map<Integer, BigInteger> map = new HashMap<>();
    int[] arr = new int[10];
    // 将i的n次方的值存入map中
    for (int i = 0; i < 10; i++) {
    BigInteger value = BigInteger.valueOf(i).pow(n);
    map.put(i, value);
    }
    getTargetNum(map, 0, n, arr);
    }

    /**

    • 此方法用来获取水仙花数,并存放在list集合中
    • @param map value中存放的是09数字的n次方,key为09
    • @param index 表示递归现在进行到arr数组的那个元素
    • @param leave 表示元素最多能够出现的次数
    • @param arr 数组的下标表示0-9这10个数字,arr数组元素的值表示下标数字出现的次数
      */
      private static void getTargetNum(Map<Integer, BigInteger> map, int index, int leave, int[] arr) {
      // 定义一个和值,即结果值
      BigInteger sum = BigInteger.ZERO;
      if (index == 9) {
      // 当下标为9时,说明之前的数字已经分配完毕
      arr[9] = leave;
      // 9的21次方出现的次数不能超过10次,因为9的21次方是21位数
      if (arr[9] < arr.length) {
      for (int i = 0; i < arr.length; i++) {
      // 用map的value值乘以数组的值
      BigInteger bigNum = map.get(i).multiply(BigInteger.valueOf(arr[i]));
      sum = sum.add(bigNum);
      }
      // 将和值转化成字符串,获取其长度
      String str = String.valueOf(sum);
      // 判断字符串长度,长度相等时再进行数字判断
      if (str.length() != N) {
      return;
      }
      if (str.length() == N) {
      // 给定一个数组用来存放结果中的数字个数
      int[] arr1 = new int[arr.length];
      for (int i = 0; i < str.length(); i++) {
      arr1[str.charAt(i) - ‘0’]++;
      }
      // 两个数组进行比较,结果一致时说明获取的sum为水仙花数
      for (int j = 0; j < arr1.length; j++) {
      if (arr[j] != arr1[j]) {
      return;
      }
      }
      list.add(sum);
      }
      }
      return;
      }
      for (int i = 0; i <= leave; i++) {
      arr[index] = i;
      getTargetNum(map, index + 1, leave - i, arr);
      }
      }
      }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值