算法_趣味整数_Question8_黑洞数(java实现)

这篇文章讲述的是算法趣味整数部分的黑洞数问题的java实现,参考的书籍为清华大学出版社出版,贾蓓等编著的《c语言趣味编程1000例》,如有错误或者不当之处,还望各位大神批评指正。

问题描述

编程求出三位数的“黑洞数”,黑洞数又称陷阱数,任何一个数字不完全相同的整数,经有限次“重排求差”操作,总会得到一个或一些数,这些数即为黑洞数。“重排求差”操作是将组成一个数的各位数字重排得到的最大数减去最小数,例如207操作序列是
702-027=675
963-369=994
954-459=495
再做下去就不变了,再用其他三位数验证也停止到了495,所以495是三位数的黑洞数

算法分析

根据题意操作步骤如下:
1. 将一个三位数拆分
2. 排列出最大数与最小数
3. 做差值,记录
4. 再找一个数进行如上操作
5. 判断运算结果是否与上一次相同若相同则输出

代码实现

package funnyInteger;

/**
 * @author 叶清逸
 * @date 2018年7月14日上午11:38:12
 * @version 1.0
 * @project funnyInteger
 */
public class Q8_BlackHoleNumber {
    /**
     * 问题描述:编程求出三位数的“黑洞数”,黑洞数又称陷阱数,任何一个数字不完全相同的整数,经有限次“重排求差”操作,总会得到一个
     *          或一些数,这些数即为黑洞数。“重排求差”操作是将组成一个数的各位数字重排得到的最大数减去最小数,例如207操作序列是
     *                                  702-027=675  
     *                                  963-369=994
     *                                  954-459=495
     *          再做下去就不变了,再用其他三位数验证也停止到了495,所以495是三位数的黑洞数
     * 
     * 算法分析:根据题意操作步骤如下:
     *                              1. 将一个三位数拆分
     *                              2. 排列出最大数与最小数
     *                              3. 做差值,记录
     *                              4. 再找一个数进行如上操作
     *                              5. 判断运算结果是否与上一次相同若相同则输出 
     */
    public static void main(String[] args) {
        /*找出一个三位数*/
        int num1 = 207 ;
        /*重排求差*/
        int first = rank(num1) ;
        /*再找个同位数排列求差*/
        int num2 = 208 ;
        int second = rank(num2) ;
        /*判断是否为黑洞数*/
        if(first == second)
            System.out.println(3+"位数的黑洞数为:"+first);
    }
    private static int rank(int number){
        int last = -1 ;
        /*将这个三位数分解*/
        int hundred = (number%1000)/100 ;
        int ten = (number%100)/10 ;
        int one = (number%10) ;
        int max = getMax(hundred , ten , one) ;
        int min = getMin(hundred , ten , one) ;
        int result = max - min ;
        /*循环求差值,直到差值与上次计算时相同*/
        while(result != last){
            last = result ;
            number = result ;
            hundred = (number%1000)/100 ;
            ten = (number%100)/10 ;
            one = (number%10) ;
            max = getMax(hundred , ten , one) ;
            min = getMin(hundred , ten , one) ;
            result = max - min ;
        }

        return result ;
    }
    /*获取排列最大值*/
    private static int getMax(int hundred , int ten , int one){
        int result = 0 ;
        if(hundred < ten){
            int t = hundred ;
            hundred = ten ;
            ten = t ;
        }
        if(hundred < one){
            int t = hundred ;
            hundred = one ;
            one = t ;
        }
        if(ten < one){
            int t = ten ;
            ten = one ;
            one = t ;
        }
        result = hundred*100 + ten*10 + one ;
        return result ;
    }
    /*获取排列最小值*/
    private static int getMin(int hundred , int ten , int one){
        int result = 0 ;
        if(hundred > ten){
            int t = hundred ;
            hundred = ten ;
            ten = t ;
        }
        if(hundred > one){
            int t = hundred ;
            hundred = one ;
            one = t ;
        }
        if(ten > one){
            int t = ten ;
            ten = one ;
            one = t ;
        }
        result = hundred*100 + ten*10 + one ;
        return result ;
    }
}
  • 问题拓展,求任意位的黑洞数
package funnyInteger;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author 叶清逸
 * @date 2018年7月14日上午11:38:12
 * @version 1.0
 * @project funnyInteger
 */
public class Q8_BlackHoleNumber {
    /**
     * 问题描述:编程求出三位数的“黑洞数”,黑洞数又称陷阱数,任何一个数字不完全相同的整数,经有限次“重排求差”操作,总会得到一个
     *          或一些数,这些数即为黑洞数。“重排求差”操作是将组成一个数的各位数字重排得到的最大数减去最小数,例如207操作序列是
     *                                  702-027=675  
     *                                  963-369=994
     *                                  954-459=495
     *          再做下去就不变了,再用其他三位数验证也停止到了495,所以495是三位数的黑洞数
     * 
     * 算法分析:根据题意操作步骤如下:
     *                              1. 将一个任意位数拆分
     *                              2. 排列出最大数与最小数
     *                              3. 做差值,记录
     *                              4. 再找一个数进行如上操作
     *                              5. 判断运算结果是否与上一次相同若相同则输出 
     */
    public static void main(String[] args) {
        /*找出一个数*/
        int num1 = 1024 ;
        /*重排求差*/
        int first = rank(num1) ;
        /*再找个同位数排列求差*/
        int num2 = 1024 ;
        int second = rank(num2) ;

        /*判断是否为黑洞数*/
        if(first == second)
            System.out.println(getLength(num1)+"位数的黑洞数为:"+first);
    }

    /*排列求差*/
    private static int rank(int number){
        int last = -1 ;                                         //存放上一次的运算结果
        /*排列求出这三位数组合的最大数与最小数*/
        int max = getMax(number) ;
        int min = getMin(number) ;
        int result = max - min ;
        while(result != last){
            last = result ;
            number = result ;
            max = getMax(number) ;
            min = getMin(number) ;
            result = max - min ;
        }
        return result ;
    }

    /*排列取得最大数*/
    private static int getMax(int number){
        int max = 0 ;
        /*使用数组来存放分解后的结果*/
        int arr[] = numToArr(number) ;
        /*求number的长度*/
        int length = arr.length ;
        /*从大到小排序*/
        Arrays.sort(arr);
        /*计算底数用于计算最小数*/
        int a = 1 ; 
        for(int j=1 ; j<length ; j++)
            a *= 10 ;
        /*将数组组成最小数*/
        for(int k=length-1 ; k>=0 ;k--){
            max += arr[k]*a ;
            a /= 10 ;
        }
        return max ;
    }

    /*排列取得最小数*/
    private static int getMin(int number){
        int min = 0 ;
        /*使用数组来存放分解后的结果*/
        int arr[] = numToArr(number) ;
        /*求number的长度*/
        int length = arr.length ;
        /*从大到小排序*/
        Arrays.sort(arr);
        /*计算底数用于计算最小数*/
        int a = 1 ; 
        for(int j=1 ; j<length ; j++)
            a *= 10 ;
        /*将数组组成最小数*/
        for(int k=0 ; k<length ;k++){
            min += arr[k]*a ;
            a /= 10 ;
        }
        return min ;
    }
    /*求参数number的长度*/
    private static int getLength(Integer number){
        int length = 1 ;
        while(number/10>0){
            length++ ;
            number /= 10 ;
        }
        return length ;
    }
    /*将数字的每一位拆分后存入数组中*/
    private static int [] numToArr(int num){
        /*获取数字的长度*/
        int length = getLength(num) ;
        /*初始化存放结果的数组*/
        int arr[] = new int [length] ;
        /*计算底数用于取出每一位的数*/
        int a = 1 ; 
        for(int j=0 ; j<length ; j++)
            a *= 10 ;

        int i = 0 ;                                                 //存放索引
        while(a/10 > 0){
            arr[i] = (num%a)/(a/10) ;
            a /= 10 ;
            i++ ;
        }
        return arr ;
    }
}

样例输出

3位数的黑洞数为:495

猜你喜欢

转载自blog.csdn.net/u013634252/article/details/81043679