大数问题:用字符串解决大数相加和相乘(转载)

在ACM的题目中经常会遇到大数相加和相乘的问题,在有些公司的面试题中也有暗含要用大数才能解决的问题。比如:输入三个整数,写一个程序判断这个三个整数能否构成一个直角三角形。此题算法很简单,但是却暗含着结果可能溢出的问题。如果不会用大数,此题就无法给出完美的答案。

下面给出大数的乘法和加法算法:

1、加法:

//  assume m is bigger than n.
char *  add( char   * a,  char   * b,  int  m,  int  n)
{
     //  为结果分配内存空间。
     char   * c  =  ( char * )malloc((m  +   2 ) *   sizeof ( char ));
    memset(c,  0 , (m  +   2 )  *   sizeof ( char ));
     //  将字符(0 + 0x30 到 9 + 0x30)转换为数字(0到9)进行计算。
     for  ( int  i  =  m, j  =  n  -   1 ; j  >=   0 ;  -- i,  -- j)
        c[i]  +=  (b[j]  -   0x30 );
     for  ( int  i  =  m, j  =  m  -   1 ; j  >=   0 ;  -- i,  -- j)
    {
        c[i]  +=  (a[j]  -   0x30 );
         if  (c[i]  >   9 )
        {
            c[i  -   1 ]  +=   1 ;
            c[i]  -=   10 ;
        }
    }
     //  将由纯数字组成的结果转换为字符串,并去除首部可能还存在的零。
   c[m + 1] = '/0';
     for  ( int  i  =   0 ; i  !=  m  +   1 ;  ++ i)
        c[i]  +=   0x30 ;
     if  (c[ 0 ]  ==   0x30 )
         for  ( int  i  =   0 ; c[i] != '/0';  ++ i)
            c[i]  =  c[i  +   1 ];
     //  返回结果所在内存单元的首地址。
     return  c;
}

2、乘法:

//  assume m is bigger than n.
char *  mult( char   * a,  char   * b,  int  m,  int  n)
{
     //  为结果分配内存空间。
     char   * c  =  ( char * )malloc((m  +  n  +   1 )  *   sizeof ( char ));
    memset(c,  0 , (m  +  n  +   1 )  *   sizeof ( char ));

     //  将字符(0 + 0x30 到 9 + 0x30)转换为数字(0到9)进行计算。
     for  ( int  i  =  m  -   1 , r  =  m  +  n  -   1 ; i  >=   0 ;  -- i,  -- r)
    {
         for  ( int  j  =  n  -   1 , k  =  r; j  >=   0 ;  -- j,  -- k)
        {
            c[k]  +=  (a[i]  -   0x30 )  *  (b[j]  -   0x30 );
             int  tmp  =  c[k]  /   10 ;
             if  (tmp  >   1 )
            {
                c[k  -   1 ]  +=  tmp;
                c[k]  -=  tmp  *   10 ;
            }
        }
    }

     //  将由纯数字组成的结果转换为字符串,并去除首部可能还存在的零。
    c[m + n] = '/0';
     for  ( int  i  =   0 ; i  !=  m  +  n;  ++ i)
        c[i]  +=   0x30 ;
     if  (c[ 0 ]  ==   0x30 )
         for  ( int  i  =   0 ;  c[i] != '/0';  ++ i)
            c[i]  =  c[i  +   1 ];

     //  返回结果所在内存单元的首地址。
     return  c;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值