大數階乘

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

/**
 * 實現思路:
 *  Step 1:int轉int[]
 *  Step 2:int[] 相乘
 *  Step 3: 將數組乘積求和
 *  Step 4: 遍歷1到n,反覆上述 Step 1 - 3即可
 *
 * 注意:1,處於後續的計算方便,在整數轉成int數組時,需要進行翻轉處理;Eg:123轉化成數組爲:[3,2,1],即整數的個位在數組的0位置
 *
 * @author yhyr
 * @since 2019/09/11 0:27
 */
public class Factorial {
    public static void main(String[] args) {
        Factorial factorial = new Factorial();
        System.out.println(factorial.factorial(20));
    }

    private String factorial(int num) {
        String result = "1";
        if (num == 0) {
            return result;
        }
        for (int i = 2; i <= num; i++) {
            int[] resultArray = str2IntArray(result);
            int[] tmpArray = str2IntArray(String.valueOf(i));
            List<String> mutList = arrayMultiplication(resultArray, tmpArray);
            result = sumStrList(mutList);
        }
        return result;
    }

    private String sumStrList(List<String> strList) {
        int[] resultArray = str2IntArray(strList.get(0));
        for (int i = 1; i < strList.size(); i++) {
            int[] strArray = str2IntArray(strList.get(i));
            resultArray = addIntegerArray(resultArray, strArray);
        }
        StringBuilder sb = new StringBuilder();
        for (int i = resultArray.length - 1; i >= 0; i--) {
            sb.append(resultArray[i]);
        }
        return sb.toString();
    }

    private int[] addIntegerArray(int[] array1, int[] array2) {
        int index = 0;
        boolean bitFlag = false; // 進位標識符
        if (array1.length < array2.length) {
            // 規定長度上的爲array1,短的爲array2
            int[] tmp = array2;
            array2 = array1;
            array1 = tmp;
        }

        while (index < array2.length) {
            int tmp = array1[index] + array2[index];
            if (bitFlag) {
                tmp += 1;
                bitFlag = false;
            }
            if (tmp < 10) {
                array1[index] = tmp;
            } else {
                array1[index] = tmp - 10;
                bitFlag = true;
            }
            index++;
        }
        if (bitFlag) {
            if (index == array1.length) {
                // 擴容處理
                int[] tmp = new int[array1.length + 1];
                for (int i = 0; i < array1.length; i++) {
                    tmp[i] = array1[i];
                }
                tmp[index] = 1;
                return tmp;
            }
            array1[index] += 1;
        }
        return array1;
    }

    /**
     * 數組乘法
     *
     * 實現思路:分別計算每一位的乘積,並用0對結果進行補位。
     *
     * Eg:24 * 25 計算思路:
     *   4 * 5 = 20 不補0
     *   2 * 5 = 10 補一個0 => 100
     *   4 * 2 = 8 補一個0 => 80
     *   2 * 2 = 4 補兩個0 => 400
     * 故最終結果爲:[20,100,80,400],對結果集求和即就是最終結果:600
     *
     * 補0判斷依據:根據兩個數在數組的下標進行判斷:
     *	 下標均爲0,則不補零
     *	 一個下標爲0另一個爲1,則補1一個零
     *	 下標均爲1,則補兩個零
     *
     * @param array1
     * @param array2
     * @return
     */
    private List<String> arrayMultiplication(int[] array1, int[] array2) {
        List<String> result = new ArrayList<>();
        for (int i = 0; i < array1.length; i++) {
            for (int j = 0; j < array2.length; j++) {
                int tmp = array1[i] * array2[j];
                StringBuilder tmpStr = new StringBuilder(String.valueOf(tmp));
                for (int k = 0; k < i + j; k++) {
                    tmpStr.append("0");
                }
                result.add(tmpStr.toString());
            }
        }
        return result;
    }

    private int[] str2IntArray(String str) {
        char[] chars = str.toCharArray();
        int[] result = new int[chars.length];
        int index = 0;
        for (int i = chars.length - 1; i >= 0; i--) {
            result[index++] = Integer.valueOf(String.valueOf(chars[i]));
        }
        return result;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章