大数乘法-HDOJ1042

这道题目把我难住了,用普通的算法通不过。查了资料才知道,这道题目属于大数相乘的问题。

思路和大整数的加法类似,利用乘法的原理解题,用整数数组来解决大数的存储问题。(因为用整型类型来存储大数会发生溢出。)

所谓的乘法原理:是指两个数相乘,其结果等于一个数与另一个数的每一位上的数字相乘后所得到的数字之和。跟我们笔算两个数的乘法是一样的。

例如:125*12 = 5*12+20*12+100*12=1500

网上有很多这道题目的代码,但都是低位存储个位的数(也就是说,数组的存储结果跟实际得到的数字顺序上是恰恰相反的,如a[0]存储的是个位的数。),理解起来很费劲。我终于找到了一个按正常顺序存储的。代码如下,有详细的注释:

#include<iostream>
#include<cstdio>
#include<memory.h>

#define MAX 10000
#define BASE 10000  //这里写10,100,1000,10000,1000000都可以,只是要注意输出格式

int h[MAX];

int main()
{
    int i,j,k,carry;
    int n;
    while(scanf("%d", &n)!=EOF)
    {
        memset(h,0,MAX*sizeof(int));    //赋值,每一个都置为0
        for(i=1,h[MAX-1]=1; i<=n; ++i)  //从i=1一直到i=n,将数组的最后一位置为1
            for(k=MAX-1,carry=0; k>=0; --k) //从最后一位开始相乘,依次向前与每一位相乘,乘积保存在carry中
            {
                carry+=i*h[k];
                h[k]=carry%BASE;
                carry/=BASE;
            }
        for(j=0;j<MAX && h[j]==0; ++j)  //从0位开始搜索,找到不为0的第一个数
            ;
        printf("%d", h[j++]);   //输出第一个不为0的位,第一位可能不足四位,就地输出!
        for( ;j<MAX; ++j)
            printf("%04d", h[j]);   //处在中间的值也可能没有四位,这时候要注意了,往左边加0,凑足四位,不然答案会出错!
        printf("\n");
    }

    return 0;
}

根据上面的原理,我写了一个大数(用数组存储)与数(用int存储)的函数:

void Multiply(int bigNum[], int bigLen, int smallNum)
{
    /**
    **说明:bigNum应该足够长,个位数存储在最后一位,高位没有的置为0
    */
    int i,j,carry=0;
    for(i=bigLen-1;i>=0;--i)
    {
        carry+=smallNum*bigNum[i];
        bigNum[i]=carry%10;
        carry=carry/10;
    }
}
上面函数中,用的是十进制,便于输出。

完整的例子如下:

#include<iostream>
#include<cstdio>
#include<memory.h>

void Multiply(int bigNum[], int bigLen, int smallNum)
{
    /**
    **说明:bigNum应该足够长,个位数存储在最后一位,高位没有的置为0
    */
    int i,j,carry=0;
    for(i=bigLen-1;i>=0;--i)
    {
        carry+=smallNum*bigNum[i];
        bigNum[i]=carry%10;
        carry=carry/10;
    }
}


int main()
{
    int i;
    int a[10]={0,0,0,0,0,0,2,3,4,5};
    int b=34;
    Multiply(a,10,b);


    for(i=0;i<10 && a[i]==0; ++i)
        ;
    for(;i<10;i++)
        printf("%d", a[i]);
    return 0;
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值