关于大整数乘法和加法的一些整理

例如,有两个大整数,a和b,其中a、b位数都是大于10的。我们知道,在做OJ的题时,碰到大整数的乘法,不能直接用a*b得到结果,那样是不对的,所以需要用数组来存储。
首先,很简单,定义两个数组(足够长),s1和s2,分别用来存储大整数a和b,因为我们需要用来相乘,而乘法是从最后一位开始乘法的,所以我们需要将a和b用数组的形式倒序存储。

int s1[100] = {0};
int s2[100] = {0};
int a, b;
cin >> a, b;
int i = 1;
while (a)
{ s1[i++] = a % 10; a /= a; }
int lena = i-1;
i = 1;
while (b)
{ s2[i++] = b % 10; b /= b; }
int lenb = i-1;

这样,数组s1和s2就分别倒序存储了大整数a和b。
此时,我们需要对数组s1和s2进行相乘,并将结果保留下来。我们知道,按照我们自然的乘法,是将大数放在上面,小数放在下面来进行相乘运算。现在,数组s1和s2分别保存了整数a和整数b,并且是倒序的方式。这样,s1的第一位就是数a的个位数,s2的第一位就是b的个位数,依次存储。此时,我们需要将长度比较长的放在外层循环,作为乘法的主体,较短的那个放在内层循环,就和我们平常做乘法一样,依次用下面的变量去乘上面的每一位。

for (i=1; i<=lena; i++)  
    { for (j=1; j<=lenb; j++) { res[i+j-1] += a[i] * b[j]; if (res[i+j-1]>9) { res[i+j] += res[i+j-1] / 10; res[i+j-1] %= 10; }  
        }  
    }  
    if (res[lena+lenb-1]>9)   
    { res[lena+lenb] += res[lena+lenb-1] / 10; res[lena+lenb-1] %= 10; lena = lena + lenb ; }  
    else lena = lena + lenb -1;

初始化数组res为0即可。
计算完成后,数组res保存的就是s1*s2的结果,并且其长度为lena;
此时res保存的结果也是按照倒序排列的,所以如果要输出a*b的结果,需要倒序输出。
有了前面的大整数的乘法,加法其实更简单,同样将大整数放入两个数组中,倒序放置,

int s1[100] = {0};
int s2[100] = {0};
int a, b;
cin >> a, b;
int i = 1;
while (a)
{ s1[i++] = a % 10; a /= a; }
int lena = i-1;
i = 1;
while (b)
{ s2[i++] = b % 10; b /= b; }
int lenb = i-1;

然后,对s1和s2进行相加,和乘法不同的是,我们将长度较小的那个放在外层循环:

if (lena < lenb)
{
    int cmp = 0;
    for (int i=1; i<=lena; ++i)
    {
        s2[i] += s1[i] + cmp;
        if (s2[i] >= 10)
        {
            cmp = s2[i] / 10;
            s2[i] %= 10;
        }
    }
    for (int i=lena+1; i<=lenb; ++i)
    {
        s2[i] += cmp;
        if (s2[i] >= 10)
        {
            cmp = s2[i] / 10;
            s2[i] %= 10;
            if (i == lenb)
            {
                s2[i+1] += cmp;
                lenb = lenb + 1;
                break;
            }
        }
    }
}

这是假设s1的长度比s2小,同理,当s2比s1小时,方法一样,最后结果存入较长的那个数组中。此时,结果数组保存值的顺序也是倒序的。

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