大数相乘

public class BigMulti {
	
	private static final int ascall = 48;
	
	/**
	 * 字符串乘法
	 * @param mul1
	 * @param mul2
	 * @return
	 */
	public static String doMul(String mul1, String mul2) {
		char[][] arrayTemp = new char[mul2.length()][mul1.length()+mul2.length()];
		initArrayZero(arrayTemp);
		for(int i = mul2.length(),j = 0; i > 0; i--,j++) {
			copyArray(arrayTemp[i-1],doMulti(mul1,mul2.charAt(i-1)),j);
		}
		return String.valueOf(doAdd(arrayTemp));
	}
	
	/**
	 * 乘法
	 * @param str1 字符串乘数
	 * @param multi2 一个字符的被乘数
	 * @return 乘法结果,用char数组返回
	 */
	private static char[] doMulti(String str1, char multi2) {
		int temp;
		int temp1;//个位
		int temp2;//十位
		char[][] arrayTemp = new char[str1.length()][str1.length()+1];
		initArrayZero(arrayTemp);
		for (int i = str1.length(), j = str1.length()+1; i > 0; i--, j--) {
			temp = (str1.charAt(i-1) - ascall) * (multi2 - ascall) ;
			temp1 = temp / 10; //
			temp2 = Math.abs(temp % 10);
			arrayTemp[i-1][j-2] = String.valueOf(temp1).charAt(0);
			arrayTemp[i-1][j-1] = String.valueOf(temp2).charAt(0);
		}
		
		return doAdd(arrayTemp);
	}
	
	/**
	 * 初始化0数组
	 * @param array
	 */
	private static void initArrayZero(char[][] array) {
		for(char[] aaa : array) {
			for(int i = 0; i < aaa.length; i++) {
				aaa[i] = '0';
			}
		}
	}
	
	
	/**
	 * 拷贝数组中字符至正确位
	 * @param targetArray
	 * @param array
	 * @param index 数组偏移量
	 */
	private static void copyArray(char[] targetArray, char[] array,int index) {
		for(int i = array.length,j = targetArray.length; i > 0; i--,j--) {
			targetArray[j-1-index] = array[i-1];
		}
	}
	
	/**
	 * 将数组中字符按位做加法运算
	 * @param array
	 * @return
	 */
	private static char[] doAdd(char[][] array) {
		char[] add = new char[array[0].length];
		for(int i = 0; i < add.length; i++ ) {
			add[i] = '0';
		}
		
		int next = 0;//进位
		for(int i = add.length; i > 0; i--) {
			int addTemp = 0;//相加中间数
			for(char[] aaa : array) {
				addTemp += (aaa[i-1] - ascall);
			}
			addTemp += next;
			int temp2 = Math.abs(addTemp % 10);
			add[i-1] = String.valueOf(temp2).charAt(0);
			next = addTemp / 10;
		}
		return add;
	}
	
	public static void main(String[] args) {
		System.out.println(doMul("45646877665412132364656456","5464564564564123852494462442040036818"));
	}
	
}


自己整理了一下:

12*34=?
乘数:12
被乘数:34


先把乘数列出来,第i行列左起第i位数,列N次(N为乘数的位数)
第二行起每次右移一位
(1) (1)
    (2) (2)

写入被乘数,按先列后行的方式
(1,3) (1,4)
      (2,3) (2,4)

将()内的数两乘
(1,3=3) (1,4=4)
        (2,3=6) (2,4=8)

相加,注意进位
(1,3=3) (1,4=4)
        (2,3=6) (2,4=8)
-------------------------
     3      10       8
         .         
-------------------------
     4       0       8

12*34=408

再看三位数乘法

123*456=?

第一步:
(1) (1) (1)
    (2) (2) (2)
        (3) (3) (3)

第二步:
(1,4) (1,5) (1,6)
      (2,4) (2,5) (2,6)
            (3,4) (3,5) (3,6)

第三步:
(1,4= 4) (1,5= 5) (1,6= 6)
         (2,4= (2,5=10) (2,6=12)
                  (3,4=12) (3,5=15) (3,6=18)

第四步:
(1,4= 4) (1,5= 5) (1,6= 6)
         (2,4= (2,5=10) (2,6=12)
                  (3,4=12) (3,5=15) (3,6=18)
----------------------------------------------
      4       13       28       27       18
           .        .        .        .
----------------------------------------------
      5        6        0        8        8

123*456=56088

    分析一下每一位的值是如何计算出来的,以下说的位都是从个位算起:
结果的第i位,是乘数的第i位乘以被乘数的1位,再加上乘数的第i-1位乘
以被乘数的第2位,一起加到乘数的第1位乘以被乘数的第i位。这样描述起
来有点不明白,画个图就很清楚了:
123*456的第3位:从乘数的第3位(1)起到第1位(3),按从右向左的方式
逐个乘以被乘数:
1*6+2*5+3*4=28

再把进位加上就可以了。
到这里,已经可以得出一个通用的计算方法,把结果逐位计算出来。

将数字字符型和整形转换 很容易 数字0的字符‘0’ASCALL码为48 

你可能感兴趣的:(大数相乘)