大树相乘的实现

最近网上做笔试题接触到这样一条题,题目是这样的:输入两个整数,要求输出这两个数的乘积。输入的数字可能超过计算机内整形数据的存储范围。

分析:

由于数字无法用一个整形变量存储,很自然的想到用字符串来表示一串数字。然后按照乘法的运算规则,用一个乘数的每一位乘以另一个乘数,然后将所有中间结果按正确位置相加得到最终结果。可以分析得出如果乘数为A和B,A的位数为m,B的位数为n,则乘积结果为m+n-1位(最高位无进位)或m+n位(最高位有进位)。因此可以分配一个m+n的辅存来存储最终结果。为了节约空间,所有的中间结果直接在m+n的辅存上进行累加。最后为了更符合我们的乘法运算逻辑,可以讲数字逆序存储,这样数字的低位就在数组的低下标位置,进行累加时确定下标位置较容易些。

下面是我的解法。

首先是对数组逆序的函数:

void reverseOrder(char* str, int p, int q)
{
    char temp;
    while(p < q)
    {
        temp = str[p];
        str[p] = str[q];
        str[q] = temp;
        p ++;
        q --;
    }
}

然后是完成大数相乘的函数:

char* multiLargeNum(char* A, char* B)
{
    int m = strlen(A);
    int n = strlen(B);
    char* result = new char[m+n+1];
    memset(result, '0', m+n);
    result[m+n] = '\0';
    reverseOrder(A, 0, m-1);
    reverseOrder(B, 0, n-1);

    int multiFlag; // 乘积进位
    int addFlag;   // 加法进位
    for(int i=0; i <= n-1; i++) // B的每一位
    {
        multiFlag = 0;
        addFlag = 0;
        for(int j=0; j <= m-1; j++) // A的每一位
        {
            // '0' - 48 = 0
            int temp1 = (A[j] - 48) * (B[i] - 48) + multiFlag;
            multiFlag = temp1 / 10;
            temp1 = temp1 % 10;
            int temp2 = (result[i+j] - 48) + temp1 + addFlag;
            addFlag = temp2 / 10;
            result[i+j] = temp2 % 10 + 48;
        }
        result[i + m] += multiFlag + addFlag;
    }
    reverseOrder(result, 0, m+n-1); // 逆序回来

    return result;
}

最后是测试程序:

int main()
{
    char A[] = "962346239843253528686293234124";
    char B[] = "93459382645998213649236498";
    char *res = multiLargeNum(A, B);
    if(res[0] != 48)
        printf("%c", res[0]);
    printf("%s", res+1);
    delete [] res;
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值