大整数乘法实现

给两个用字符串表示的大整数,对这两个整数进行相乘,求它们的积,所谓大整数就是用int,long均无法表示的整数,对它们做乘法,只能自己来实现。

我们假定两个整数是十进制的正数,我们做这样的假定只是为了研究大整数乘法的方法,至于其他进制,有正负之分只要在这种方法上稍微做点修改就行了。下面开始讲解。

1.方法1两个数相乘,最先想到的方法就是,我们可以用加法来实现,对被乘数做乘数次加法,进行一个循环就可以很容易的得到。当然这个方法可以做一个优化,对于输入的两个字符串整数,可以先比较一下两个数的大小,用较小的数做乘数,这样可以减少循环的次数。比较两个数的大小比较容易,第一步先比较两个数的长度,较短的数小;如果长度相同就比较两个数的第一个字符,如果有一个较小,就用那个数作为乘数;如果长度相同且第一个字符也相同,我们就随便选择一个作为被乘数。如果要完整的实现这个方法,需要定义字符串表示整数的加法运算和减法运算。这种方法虽然能够实现两个整数的乘法但是缺点也是明显的,那就是循环的次数过多。加入被乘数的长度是N,乘数的长度是M,坏的情况下,循环的次数是10的M次方-1,在计算的过程中每次循环需要对被乘数的操作次数为N+M/2次,需要对乘数测操作次数是M/2次,这样时间复杂度就为10的M次方(N + M)。这个复杂度是很难让人接受的。

2.方法1我们算是一种比较基本的方法,它的缺陷也是很明显的,有没有一种很好的方法呢?当然有的,第二种方法,我们不再循环乘数次,对被乘数进行加法操作。先保存一份被乘数副本,我们从乘数的个位开始,取得个位上的数字,假设为a, 对被乘数进行a次自加操作,将结果保存起来,重新加载一次被乘数;然后取乘数十位上的数字,假设为b,先将被乘数左移一位,对被原先乘数进行b次循环自加;最后将结果与第一次保存的结果向加。一次次执行这种操作,直到循环乘数的位数次,结束。被乘数保存的值就是相乘的结果值。这种方法的性能就比较好了,对乘数和被乘数分别进行了乘数位数次循环,对被乘数进行了乘数上所有位上数字的和的次循环自加。

3.还有没有比方法2更好的办法呢?答案是肯定的,这种方法是对方法2自加一步进行了优化,在每次取个位上数字之后,假设为a, 不在对被乘数进行a次自加,而是将a与被乘数上的每位进行相乘,相乘之后再加上低位上的进位,得到的结果除于10得到向高位的进位,与10取余得到该位的数字,依次对被乘数上的每位上的数进行这个操作。这样下来,我们仅对被乘数进行了乘数的位数次循环,每次循环对仅对乘数上的每位数进行了一次操作。这种方法的时间复杂度是不是非常低了。

利用上述方法,经过进一步的改进就可以解决其他进制的乘法,也可以解决有正负之分的乘法。

    原文作者:大整数乘法问题
    原文地址: https://blog.csdn.net/catchertherye/article/details/11826629
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞