大整数相乘算法-Java实现

我们知道,在Java中最大的整数就是Long.MAX_VALUE(0x7fffffffffffffff,也即9223372036854775807),要想表示更大的整数就必须通过自定义的类来表示了,比如java.math.BigInteger。

算法需求是这样的:输入两个大整数(长度不定,可以达到几百上千位),然后计算他们的乘积

在大整数算法实现中,我们往往按照最原始的乘法竖式运算法了,这也是我们算法实现的基本思想基础。当然在实现过程中,我们会有所变换。

首先,贴出小学生都会的按位竖式计算代码:

package com.wl.test;

import java.util.Scanner;

public class Main {
	
	public static void main(String[] args) {
	
		Scanner scanner = new Scanner(System.in);
		String var1 = scanner.nextLine();
		String var2 = scanner.nextLine();
		scanner.close();
		operate_1bit(var1, var2);
	}
	
	public static void operate_1bit(String var1, String var2) {
	
		// 长度分别为m和n的两个整数相乘,他们的乘积为m+n或者m+n-1位
		int[] mid_result = new int[var1.length() + var2.length()];
		
		// 初始化为0
		for(int i=0; i<mid_result.length; i++)
			mid_result[i] = 0;
		
		for(int i=var1.length()-1; i>=0; i--) {
			// 获取var1的第i位上的整数
			int vi = var1.charAt(i) - '0';
			for(int j=var2.length()-1; j>=0; j--) {
				// 获取var2的第j位上的整数
				int vj = var2.charAt(j) - '0';
				// 相乘并累加
				mid_result[i + j + 1] += (vi * vj);
			}
		}
		
		// 处理进位
		for(int i=mid_result.length-1; i>0; i--) {
			mid_result[i-1] += (mid_result[i]/10);
			mid_result[i] %= 10;
		}
		
		// 打印结果
		for(int i=(mid_result[0]==0?1:0); i<mid_result.length; i++) {
			System.out.print(mid_result[i]);
		}
	}
	
}




下面用一表格演示代码实现过程




如果搞清楚了按位计算的方法,那我们便可以按三位来计算了,计算的思想是一样的,只不过,我们把两个整数字符串从右到左按3位一组划分,然后计算。


先贴上代码

package com.wl.test;

import java.util.Scanner;

public class Main {
	
	public static void main(String[] args) {
	
		Scanner scanner = new Scanner(System.in);
		String var1 = scanner.nextLine();
		String var2 = scanner.nextLine();
		scanner.close();
		operate_3bit(var1, var2);
	}
	
	public static void operate_3bit(String var1, String var2) {
		
		String[] result1 = partition(var1);
		String[] result2 = partition(var2);
		
		int[] mid_result = new int[result1.length + result2.length];
		for(int i=0; i<mid_result.length; i++)
			mid_result[i] = 0;
		
		for(int i=result1.length-1; i>=0; i--) {
			int vi = Integer.parseInt(result1[i]);
			for(int j=result2.length-1; j>=0; j--) {
				int vj = Integer.parseInt(result2[j]);
				mid_result[i + j + 1] += (vi * vj);
			}
		}
		
		for(int i=mid_result.length-1; i>0; i--) {
			mid_result[i-1] += (mid_result[i]/1000);
			mid_result[i] %= 1000;
		}
		
		for(int i=(mid_result[0]==0?1:0); i<mid_result.length; i++) {
			System.out.print(mid_result[i]);
		}
	}
	
	private static String[] partition(String var) {
		
		String[] parts = new String[(int) Math.ceil(var.length()/3.0)];

		int i, j;
		for(i=var.length(), j=parts.length-1; i>=4; i-=3,j--) {
			parts[j] = var.substring(i-3, i);
		}
		parts[j] = var.substring(0, i);
		return parts;
	}
}
其中,partition函数用于将字符串分割成3位一组的字符串数组,注意分割是从字符串后面往前面进行的,也就是说字符串数组中第一个字符串可能并不是3位,也有可能是一位或两位。


从表格中我们继续分析代码过程




不要问我结果在哪儿,进位的那一行拼起来就是结果了。


下面是上面两种方法计算的情况:


第一、二行是输入,第三行是通过按位计算得出的结果,第四行是通过按3位计算得出的结果。



参考文章:http://blog.csdn.net/tjsinor2008/article/details/5625849

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值