1. 程式人生 > >兩個大數相加和兩個大數相乘-------java版(曾經面試遇到過)

兩個大數相加和兩個大數相乘-------java版(曾經面試遇到過)

    瀏覽部落格偶然看到https://blog.csdn.net/Colin_Qichao/article/details/81538327中給出的大數相乘演算法,想到曾經有次面試時也被問到了該問題,於是仔細的研究了一下,並按照其思路寫了一個兩個大數相加的演算法(這個問題也被面試官問到過....),現將演算法貼出,與大家共享,如有問題,希望有人指出...

package cn.nrsc.algorithm.bigdata;

/**
 * 
 * @author 孫川----兩個大數進行相加
 *
 */
public class BigDataPlus {
	public static void main(String[] args) {

		String num1 = "123456";
		String num2 = "67891011";
		String result = bigDataPlus(num1, num2);
		System.out.println(result);
	}

	// 兩個大數相加的演算法
	private static String bigDataPlus(String str1, String str2) {

		int len1 = str1.length();
		int len2 = str2.length();
		// 兩個大數相加,相加後位數的最大值----比兩個數中較大的那個數的位數多1
		int len = len1 > len2 ? len1 + 1 : len2 + 1;

		// 存放相加後各個位上的和
		int[] tmp = new int[len];

		// 反轉字串,便於從低位到高位相加和最高位的進位導致和的位數增加
		str1 = reverse(str1);
		str2 = reverse(str2);

		// 讓兩個字串位數相同,不足的在後面補0,這樣才能個位+個位,十位+十位,百位+百位+等等等
		if (len1 < len2)
			for (int i = len1; i < len2; i++)
				str1 += "0";
		else
			for (int i = len2; i < len1; i++)
				str2 += "0";

		// 兩個大數相加------個位+個位,十位+十位,百位+百位+等等等

		// 字元轉int 如將char型別的'9'轉成int型別的9,只需 (int)'9' - (int)'0'
		for (int j = 0; j < str1.length(); j++)
			tmp[j] = (int) str1.charAt(j) - (int) '0' + (int) str2.charAt(j) - (int) '0';

		// 進位問題
		for (int j = 0; j < tmp.length; j++) {
			// 判斷是否需要進位
			if (tmp[j] / 10 > 0)
				// 更高位置進位
				tmp[j + 1] += tmp[j] / 10;
			// 取該位置對應數字
			tmp[j] = tmp[j] % 10;

		}

		int m = 0;
		for (int i = len - 1; i >= 0; i--) {
			// 陣列下標對應較高位置,即結果較高位數可能有多個0,不需要遍歷應去除
			if (tmp[i] > 0) {
				m = i;
				break;
			}
		}
		StringBuilder sb = new StringBuilder();
		// 從結果最高不為0位置開始遍歷
		for (int i = m; i >= 0; i--) {
			sb.append(tmp[i]);
		}

		return sb.toString();
	}

	// 反轉字串
	private static String reverse(String str) {

		if (str == null || str.length() == 1)
			return str;
		return reverse(str.substring(1)) + str.charAt(0);
	}
}

為了對比,也把大數相乘演算法列在下面,來源於https://blog.csdn.net/Colin_Qichao/article/details/81538327

package cn.nrsc.algorithm.bigdata;

/**
 * {大數相乘演算法}
 * @author 來源於https://blog.csdn.net/Colin_Qichao/article/details/81538327
 */
public class BigDataMultiply {
	public static void main(String[] args) {
		String str1 = "753656566859769";
		String str2 = "9518598598486568654";
		// 字串反轉,希望後面生成的陣列位置0對應個位,位置1對應十位,位置2對應百位
		str1 = reserve(str1);
		str2 = reserve(str2);
		int len1 = str1.length();
		int len2 = str2.length();
		int len = len1 + len2 + 3;

		char[] chars1 = str1.toCharArray();
		char[] chars2 = str2.toCharArray();
		int a[] = new int[len1];
		int b[] = new int[len2];
		int c[] = new int[len];
		for (int i = 0; i < len1; i++) {
			a[i] = Integer.valueOf(String.valueOf(chars1[i]));
		}
		for (int i = 0; i < len2; i++) {
			b[i] = Integer.valueOf(String.valueOf(chars2[i]));
		}
		String result = countMultiply(c, a, b, len, len1, len2);
		System.out.println(result);
	}
	

	private static String countMultiply(int[] c, int[] a, int[] b, int len, int len1, int len2) {
		for (int i = 0; i < len1; i++) {
			for (int j = 0; j < len2; j++) {
				// 核心程式碼:相乘結果各個位置上的值和乘數對應的位置有關聯。
				// 例如:結果個位上的數值只能由乘數個位上的數相乘取個位。
				c[i + j] += a[i] * b[j];
			}
		}
		for (int i = 0; i < len; i++) {
			if (c[i] / 10 > 0) {// 判斷是否需要進位
				// 更高位置進位
				c[i + 1] += c[i] / 10;
			}
			// 取該位置對應數字
			c[i] = c[i] % 10;
		}
		int m = 0;
		for (int i = len - 1; i >= 0; i--) {
			// 陣列下標對應較高位置,即結果較高位數可能有多個0,不需要遍歷應去除
			if (c[i] > 0) {
				m = i;
				break;
			}
		}
		StringBuilder sb = new StringBuilder();
		// 從結果最高不為0位置開始遍歷
		for (int i = m; i >= 0; i--) {
			sb.append(c[i]);
		}

		return sb.toString();
	}

	private static String reserve(String str1) {
		if (str1 == null || str1.length() == 1) {
			return str1;
		} else {
			return reserve(str1.substring(1)) + str1.charAt(0);
		}
	}
}