大数相乘

import java.math.BigInteger;
import java.util.Scanner;
import org.junit.Test;

public class Inter {
  @Test
  public void bigMultiply()
  {
	  Scanner sc=new Scanner(System.in);
	  //输入两个字符串
	  String s1=sc.next();
	  String s2=sc.next();
	  //记录下数字串的长度,以后要使用
	  int n1=(s1.trim()).length();
	  int n2=(s2.trim()).length();
	  //创建两个数组,来存放数组的每一位
	  int a1[]=new int[n1];
	  int a2[]=new int[n2];
	  //赋值,这里需要注意的是要倒序来赋值
	  for(int i=0;i<n1;i++)
		  a1[i]=Integer.parseInt(s1.charAt(n1-1-i)+"");
	  for(int i=0;i<n2;i++)
		  a2[i]=Integer.parseInt(s2.charAt(n2-1-i)+"");
	  //一个二维数组,来模拟每次相乘的时候的结果
	  int results[][]=new int[n2][n1+n2];
	  for(int i=0;i<n2;i++)
	  {
		  for(int j=0;j<n1;j++)
		  {
			  results[i][i+j+1]+=(a1[j]*a2[i])/10;//向上一位进位
			 results[i][i+j]+=(a1[j]*a2[i])%10;//本位数字要加上原来的进位,所以是+=
		  }
	  }
	 //一维数组记录最后的结果
	  int result[]=new int[n1+n2+1];
	  //进位标志
	  int jin=0;
	  for(int i=0;i<n1+n2;i++)

      {
		  int sum=0;
		  sum+=jin;
		  for(int j=0;j<n2;j++)
		  {
			  sum+=results[j][i];
		  }
		  jin=sum/10;
		  result[i]=sum%10;
      }
	  int index=n1+n2-1;
	  //将前几位为零的省略
	  while(result[index]==0)
		  index--;
	  //输出最后的结果
	  for(int i=index;i>=0;i--)
		  System.out.print(result[i]);
	 
 }
  @Test
  public void moni()
  {
	  Scanner sc=new Scanner(System.in);
	  String s1=sc.next();
	  String s2=sc.next();
	  BigInteger b1=new BigInteger(s1.trim());
	  BigInteger b2=new BigInteger(s2.trim());
	  BigInteger b=b1.multiply(b2);
	  System.out.println(b.toString());
	  
  }
  
}


 大数相乘需要解决的是存储的问题。开始看到这个问题的时候,翻了翻算法课本,发现是用分治法,自己写了写,模拟了一下,发现到加法的时候还是无法避免溢出的问题,看到网上一些人们用的就是普通数组来做,我也采用了如此的方案,不过实现的步骤,我没有参考别人的,是完全按照自己算乘法的步骤来实现的。如果从思考上来说,不难,可是数组量大,而且还要考虑进位的问题,所以处理的时候有许多细节需要注意,比如说,你输入的数字,存入数组中的时候要先进行倒序,开始的时候我没有注意,算11*11是正确的,算25*25的时候就开始出错了,找了好半天才发现原来是存储的时候出了很大的问题。比如说,相乘进位的情况,如果不考虑当前运算对高位的影响,也就是不考虑向上进位,必然会出错了,而且计算的时候还要接收从低位进上来的。最后所有的中间结果进行相加的时候,更要注意进位的情况。

   我用的是单元测试来做的,原来的题目要计算的是1234567891011121314151617181920*2019181716151413121110987654321,我先使用的是自己设计的算法,下面使用的是Java中的大整数来计算,结果是相同的,2492816912877266687794240983772975935013386905490061131076320

  这个问题,现在想想还是很有意思的,有两天时间,闲来无事的时候我就开始拿笔模拟,感觉没有什么错误了就上机实践,可是总会出现一些意想不到的问题。不过,凭借着对问题的把握,还是可以找到问题的根源的。下次再碰到这样的问题就知道该怎么办了,所以,记录一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值