华为经典面试题---大数乘法的c++实现

来源:互联网 发布:may it be mv 编辑:程序博客网 时间:2024/06/05 08:19

32位机器上的最大有符号数为2147483647,最大无符号数是4294967295。这对于实际的计算显然是不够的,于是就产生了大数乘法的需求。其思路不算难,按照我们平时计算两个数的乘积的流程就行了。如果你使用的是c语言等不能动态扩展数组的语言,有一个需要考虑的问题是:两数相乘后的位数为多少?这需要一点点的数学知识,两数乘积的位数不大于两数的位数之和。所以需要提前分配好足够的空间。我这里使用c++来实现,不考虑此问题。

思路:

  1. 从较短的数的各位开始循环(外层循环次数少,有利于提高效率),用短数的各位去逐个乘以长数的每个位,得到一个乘积,内层循环结束;取短数的十位,逐个乘以长数的每一位,再次得到一个乘积,用之前的乘积累加上这次的乘积;如此以往,直至外层循环结束,最后加上进位位,得到最终结果。

下面来看代码:

#include <iostream>using namespace std;string BigIntAdd(string &tmp, string &ret){    int lena = tmp.length();    int lenb = ret.length();    const char* pa = tmp.c_str();    const char* pb = ret.c_str();    int i = lena - 1;    int j = lenb - 1;    int carry = 0;    string addup;    while(i >= 0 || j >= 0)    {        int sum = 0;        if(i >= 0)        {            sum += pa[i]-0x30;            i--;        }        if(j >= 0)        {            sum += pb[j]-0x30;            j--;        }        sum += carry;        addup = to_string(sum % 10) + addup;        carry = sum / 10;    }    if(carry)        addup = to_string(carry) + addup;    return addup;}string BigIntTimes(string &a, string &b){    int lena = a.length();    int lenb = b.length();    int shoter = 0;    int longer = 0;    const char* pshoter;    const char* plonger;    if(lena > lenb)    {        shoter = lenb;        longer = lena;        pshoter = b.c_str();        plonger = a.c_str();    }    else    {        shoter = lena;        longer = lenb;        pshoter = a.c_str();        plonger = b.c_str();    }    string tmp;    string ret = "0";    int zero = 0;    for(int i = shoter-1; i >= 0; i--)    {        int blow = pshoter[i]-0x30;        int carry = 0;        int product = 0;        tmp.append(zero++, '0');        for(int j = longer-1; j >= 0; j--)        {            product = blow * (plonger[j]-0x30) + carry;            tmp = to_string(product % 10) + tmp;            carry = product / 10;        }        if(carry)            tmp = to_string(carry) + tmp;        ret = BigIntAdd(tmp, ret);        tmp.clear();    }    return ret;}int main(int argc, char const *argv[]){    string a;    string b;    if(argc == 3)    {        a.assign(argv[1]);        b.assign(argv[2]);    }    cout << "BigIntTimes: " << BigIntTimes(a, b) << endl;    return 0;}

注意到函数string BigIntTimes(string &a, string &b)负责计算乘积,但要实现此函数,先要实现一个大数加法的函数string BigIntAdd(string &tmp, string &ret),思路类似,但更简单。

测试

该题原题让求1234567891011121314151617181920 * 2019181716151413121110987654321两数的乘积,
我们先用python算出正确结果,结果为2492816912877266687794240983772975935013386905490061131076320,如下图:
correct
实际计算的结果如下图:
really
计算结果正确!

0 0
原创粉丝点击