LeetCode 43. Multiply Strings

题目

Given two numbers represented as strings, return multiplication of the numbers as a string.

Note: The numbers can be arbitrarily large and are non-negative.

分析

这道题是2016年3月28日阿里内推笔试的第二题. 假设输入的字符串长度分别为 len1 和 len2, 那么两者之积所得字符串的长度不会超过 len1+len2. 因此分配长度为 len1+len2+1的字符数组存储最终计算结果.

令 num1 指向较长 (如果长度不等) 的字符串, num2 指向另一字符串.
注意 num1 和 num2 所代表的数字的最低位都是字符串的最后一个元素. 从num1所代表的数字的最低位开始依次向高位前进, 把每一位与 num2 所指代的数字的每一位 (从低到高) 相乘. 由于两位相乘可能产生进位carry, 同时由于仅使用了一维数组, 因此结果数组中可能存在上一轮计算已有的结果upper, 要把这两项加入乘积, 得到tmp. 随后根据tmp得出新的进位以及存入结果数组的数值.

计算结束后, 结果数组从后向前遍历, 找到第一个非0元素, 然后将字符串转置, 最终返回结果.

解答

char* multiply(char* num1, char* num2) {
    int len1 = strlen(num1);
    int len2 = strlen(num2);
    // the length of the result is at most len1+len2
    // +1 to store '\0'
    char *result = malloc(sizeof(char) * (len1+len2+1));
    memset(result, '0', sizeof(char) * (len1+len2+1));
    result[len1+len2] = '\0';

    if (len1 < len2) {
        // make num1 point to the longer one
        char *t;
        int templen;
        t = num1; num1 = num2; num2 = t;
        templen = len1; len1 = len2; len2 = templen;
    }
    for (int i = len1 - 1; i >= 0; i--) {
        // bdi means base digit index
        // for each i, it is the index of the silo in `result`
        // to which the lowest digit of the product is stored
        int bdi = len1-1-i;
        int a = num1[i] - '0';
        int carry = 0;
        int k = 0;
        for (int j = len2 - 1; j >= 0; j--) {
            int b = num2[j] - '0';
            // k is the index of the silo in `result`
            // to which the last digit of the
            // current product is stored. It can also be
            // used to access previous digit stored in this silo,
            // i.e. `upper`
            k = bdi + (len2-1-j);
            int upper = result[k] - '0';
            int tmp = a * b + upper + carry;
            carry = tmp / 10;
            result[k] = tmp % 10 + '0';
        }
        // if there is a carry, store it to the next digit
        if (carry > 0) {
            result[k+1] = carry + '0';
        }
    }
    int i;
    // skip leading zeros
    for (i = len1+len2-1; i >= 0; i--) {
        if (result[i] != '0') {
            break;
        }
    }
    if (i < 0) {
        // didn't come here from break, so all digits
        // are zero, thus the result is zero
        result[1] = '\0';
        return result;
    }

    result[i+1] = '\0'; // terminate the string
    // reverse the string
    for (int j = 0; j < (i + 1) / 2; j++) {
        char tmp = result[j];
        result[j] = result[i-j];
        result[i-j] = tmp;
    }
    return result;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值