1. 程式人生 > >大整數階乘的java實現

大整數階乘的java實現

在實現K2演算法時,用到了階乘,如果資料量過大,普通階乘會導致溢位,所以需要用到大整數階乘。

public class BigIntegerArr {
	/**
	 * 計算進位
	 * 
	 * @param bit
	 *            陣列
	 * @param pos
	 *            用於判斷是否是陣列的最高位
	 */
	private void carry(int[] bit, int pos) {
		int i, carray = 0;
		for (i = 0; i <= pos; i++)// 從0到pos逐位檢查是否需要進位
		{
			bit[i] += carray;// 累加進位
			if (bit[i] <= 9) // 小於9不進位
			{
				carray = 0;
			} else if (bit[i] > 9 && i < pos)// 大於9,但不是最高位
			{
				carray = bit[i] / 10;// 儲存進位值
				bit[i] = bit[i] % 10;// 得到該位的一位數
			} else if (bit[i] > 9 && i >= pos)// 大於9,且是最高位
			{
				while (bit[i] > 9)// 迴圈向前進位
				{
					carray = bit[i] / 10;// 計算進位值
					bit[i] = bit[i] % 10;// 當前的第一位數
					i++;
					bit[i] = carray;// 在下一位儲存進位值
				}
			}
		}
	}

	/**
	 * 大整數階乘
	 * 
	 * @param bigInteger
	 *            所計算的大整數
	 */
	public String bigFactorial(int bigInteger) {
		int pos = 0;//
		int digit;// 資料長度
		int a, b;
		int m = 0;// 統計輸出位數
		int n = 0;// 統計輸出行數
		double sum = 0;// 階乘位數
		for (a = 1; a <= bigInteger; a++)// 計算階乘位數
		{
			sum += Math.log10(a);
		}
		digit = (int) sum + 1;// 資料長度

		int[] fact = new int[digit];// 初始化一個數組
		fact[0] = 1;// 設個位為 1

		for (a = 2; a <= bigInteger; a++)// 將2^bigInteger逐個與原來的積相乘
		{
			for (b = digit - 1; b >= 0; b--)// 查詢最高位{}
			{
				if (fact[b] != 0) {
					pos = b;// 記錄最高位
					break;
				}
			}

			for (b = 0; b <= pos; b++) {
				fact[b] *= a;// 每一位與i乘
			}
			carry(fact, pos);
		}

		for (b = digit - 1; b >= 0; b--) {
			if (fact[b] != 0) {
				pos = b;// 記錄最高位
				break;
			}
		}
		// System.out.println(bigInteger +"階乘結果為:");
		// for(a = pos ; a >= 0 ; a --)//輸出計算結果
		// {
		// System.out.print(fact[a]);
		// m++;
		// if(m % 5 == 0)
		// {
		// System.out.print(" ");
		// }
		// if(40 == m )
		// {
		// System.out.println("");
		// m = 0 ;
		// n ++;
		// if(10 == n )
		// {
		// System.out.print("\n");
		// n = 0;
		// }
		// }
		// }
		// System.out.println("\n"+"階乘共有: "+(pos+1)+" 位");
		return reverseArray(fact);
	}

	private String reverseArray(int[] fact) {
		StringBuilder sb = new StringBuilder();
		for (int i = fact.length - 1; i >= 0; i--) {
			sb.append(String.valueOf(fact[i]));
		}
		return sb.toString();

	}

	private Double toLogBig(String intStr) {
		// String intStr = "";
		String deciStr = "";
		int len = intStr.indexOf(".");
		if (len == 0 || len == intStr.length() - 1) {
			return 0.0;
		} else if (len == -1) {
			deciStr = "0";
		} else {
			deciStr = intStr.substring(len + 1, intStr.length());
			intStr = intStr.substring(1, len);
		}
		len = intStr.length();
		while (len > 1) {
			if (intStr.startsWith("0")) {
				intStr = intStr.substring(1, len);
				len -= 1;
			} else {
				break;
			}
		}
		len = deciStr.length();
		while (len > 1) {
			if (deciStr.endsWith("0")) {
				deciStr = deciStr.substring(0, len - 1);
				len -= 1;
			} else {
				break;
			}
		}
		double ret;
		len = intStr.length();
		if (len < 16) {
			if (intStr.length() > 4 || deciStr.length() < 9) {
				intStr += "." + deciStr;
				ret = Double.valueOf(intStr);
				if (ret == 0) {
					return 0.0;
				}
				ret = Math.log10(ret);
			} else {
				len = deciStr.length();
				intStr = intStr + deciStr.substring(0, len - 8);
				deciStr = deciStr.substring(len - 8, len);
				ret = 8 - len;
				len = intStr.length();
				while (len > 1) {
					if (intStr.startsWith("0")) {
						intStr = intStr.substring(1, intStr.length());
					} else {
						break;
					}
				}
				len = intStr.length();
				if (len > 9) {
					len -= 8;
					deciStr = intStr.substring(8, len + 8) + deciStr;
					intStr = intStr.substring(0, 8);
					ret += len;
				}
				intStr += "." + deciStr;
				ret += Math.log10(Double.valueOf(intStr));
			}
		} else {
			len = intStr.length();
			deciStr = intStr.substring(9, len) + deciStr;
			intStr = intStr.substring(0, 9) + "." + deciStr;
			len -= 9;
			ret = Math.log10(Double.valueOf(intStr)) + Double.valueOf(len);
		}
		return ret;
	}

//	public static void main(String[] args) {
//		BigIntegerArr bi = new BigIntegerArr();
//		bi.bigFactorial(112);
//		System.out
//				.println(bi
//						.toLogBig("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"));
//
//	}
}


相關推薦

整數java實現

在實現K2演算法時,用到了階乘,如果資料量過大,普通階乘會導致溢位,所以需要用到大整數階乘。 public class BigIntegerArr { /** * 計算進位 * * @param bit * 陣列 * @para

分治演算法-整數相乘(JAVA實現

 上大學演算法分析實驗課的內容.關於利用分治法大整數乘法.還沒有解決大整數的儲存方式,應該是要利用一維陣列來解決.所以目前只是5位數的運算沒有問題.程式健全  1/** *//** 2 * 大整數項乘 3 * @author Administrator 4 * 5 */ 6import java.io.B

大數Java實現

題目 描述 我們都知道如何計算一個數的階乘,可是,如果這個數很大呢,我們該如何去計算它並輸出它? 輸入輸入一個整數m(0<m<=5000) 輸出輸出m的階乘,並在輸出結束之後輸入一個換行符 樣例輸入 50 樣例輸出 30414093201713378

Java:演算法 - 求正整數n!

數學公式:n!=1 * 2 * 3…(n-2) * (n-1) * n 應用方面:伽瑪函式與排列組合 遞迴實現程式碼: public static long fac(int n){ if(n == 0 || n ==1) return 1;

JavaScript中實現一個整數的方法

計算一個整數的階乘,如果用字母n來代表一個整數,階乘代表著所有小於或等於n的整數的乘積。階乘通常簡寫成 n!     例如: 5! = 1 * 2 * 3 * 4 * 5 = 120(1)第一種方法使用for迴圈來實現階乘的效果function factorialize(nu

資料運算-java高精度運算

import java.math.BigDecimal; /**  * 高精度運算  * @author RSun  * @Date 2012-11-7下午11:22:04  */ public class TestBigInteger {

6-8 簡單計算(10 分) 本題要求實現一個計算非負整數的簡單函式。

int Factorial( const int N ); 其中N是使用者傳入的引數,其值不超過12。如果N是非負整數,則該函式必須返回N的階乘,否則返回0。int Factorial( const int N ){  int fa=0;  if(N>=0)  { fa

6-10 計算升級版(20 分) 本題要求實現一個列印非負整數的函式。

https://pintia.cn/problem-sets/14/problems/742#include <stdio.h> void Print_Factorial ( const int N ); int main() { int N;

Code Kata:整數比較大小&整數四則運算---加減法 javascript實現

字符串類型 基本實現 lac 也有 算法 amp 比較大小 var line 大整數的四則運算已經是老生常談的問題了。很多的庫也已經包含了各種各樣的解決方案。 作為練習,我們從最簡單的加減法開始。 加減法的核心思路是用倒序數組來模擬一個大數,然後將兩個大數的利用豎式進行運算

排序算法Java實現

nbsp main 計數 計數器 希爾 sele style div lec 1.冒泡排序Bubble Sort public class BubbleSort { public static void main(String[] args) {

suseoj 1207: 整數的乘法(java, 大數相乘)

描述 ann ron reat n) 不能 creat ble 一個 1207: 大整數的乘法 時間限制: 1 Sec 內存限制: 128 MB提交: 7 解決: 2[提交][狀態][討論版][命題人:liyuansong] 題目描述 求兩個不超過200位的非負整數的

求n的 (python實現

描述 給定一個數n,範圍為0≤n≤100,請你程式設計精確的求出n的階乘n!。 輸入 輸入資料有多行,每行一個整數n,當n<0時輸入結束。 輸出 輸出n的階乘。 樣例輸入 1234-1 樣例輸出  12624 def fact(n):

整數求和演算法java

package com.text1; import java.util.Scanner; /* * 大整數求和演算法 */ public class SubBignum{ public static void add(int[] a,int[] b) { int[] p; int

整數加減法c/c++實現

大整數加法 # include <iostream> using namespace std; template<typename T> int count(T& x) {     int s1 = sizeof(x);  

量級 - HDU-2674 N!Again

 N!Again Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6338  

經典排序演算法(Java實現)

import java.util.ArrayList; import java.util.Arrays; /** * @author lollipop * @email [email protected] * @date 2018/11/22 0022 8:36 *

基於快排實現,在N個亂序的陣列中找第K的數(Java實現

類似於快速排序,執行一次快速排序之後,每次只選擇一部分繼續執行快速排序,直到找到第K大個元素為止,這個元素在陣列位置後面的元素即為所求。 時間複雜度:O(n) 利用快排的思想,從陣列arr中隨機找出一個元素X,把陣列分成兩部分arr_a和arr_b。 arr_a中的元素比x大,arr_b中的元素比x小。 這

整數相加連結串列實現(Add Two Numbers)

與其他實現不同點:常數空間複雜度,複用其中一條連結串列來儲存結果! 例子: a:122349 b:43544 public ListNode addTwoNumbers(ListNode l1, ListNode l2) { if(null == l1){

資料

import java.math.BigDecimal; /** 大資料階乘 * @author lsh * */ public class Jiechen { public static void main(String[] args) { System

求任意數的java程式碼

一.求解輸入任意一個數的階乘1.階乘 :n!=n*(n-1).......*3*2*12.程式碼:import java.util.Scanner;//導包   public class NumberSumTest {//求解階乘public static void main