力扣第四十三题——字符串相乘

内容介绍

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。

示例 1:

输入: num1 = "2", num2 = "3"
输出: "6"

示例 2:

输入: num1 = "123", num2 = "456"
输出: "56088"

提示:

  • 1 <= num1.length, num2.length <= 200
  • num1 和 num2 只能由数字组成。
  • num1 和 num2 都不包含任何前导零,除了数字0本身。

完整代码

 char* addStrings(char* num1, char* num2) {
    int i = strlen(num1) - 1, j = strlen(num2) - 1, add = 0;
    char* ans = malloc(sizeof(char) * (i + j + 5));
    int ansLen = 0;
    while (i >= 0 || j >= 0 || add != 0) {
        int x = i >= 0 ? num1[i] - '0' : 0;
        int y = j >= 0 ? num2[j] - '0' : 0;
        int result = x + y + add;
        ans[ansLen++] = result % 10;
        add = result / 10;
        i--;
        j--;
    }
    for (int i = 0; i < ansLen / 2; i++) {
        char t = ans[i];
        ans[i] = ans[ansLen - 1 - i];
        ans[ansLen - 1 - i] = t;
    }
    for (int i = 0; i < ansLen; i++) {
        ans[i] += '0';
    }
    ans[ansLen++] = 0;
    return ans;
}

char* multiply(char* num1, char* num2) {
    int m = strlen(num1), n = strlen(num2);
    char* ans = malloc(sizeof(char) * 2);
    ans[0] = '0', ans[1] = 0;
    if ((m == 1 && num1[0] == '0') || (n == 1 && num2[0] == '0')) {
        return ans;
    }
    for (int i = n - 1; i >= 0; i--) {
        char* curr = malloc(sizeof(char) * (n + m + 5));
        int currLen = 0;
        int add = 0;
        for (int j = n - 1; j > i; j--) {
            curr[currLen++] = 0;
        }
        int y = num2[i] - '0';
        for (int j = m - 1; j >= 0; j--) {
            int x = num1[j] - '0';
            int product = x * y + add;
            curr[currLen++] = product % 10;
            add = product / 10;
        }
        while (add != 0) {
            curr[currLen++] = add % 10;
            add /= 10;
        }
        for (int i = 0; i < currLen / 2; i++) {
            char t = curr[i];
            curr[i] = curr[currLen - 1 - i];
            curr[currLen - 1 - i] = t;
        }
        for (int i = 0; i < currLen; i++) {
            curr[i] += '0';
        }
        curr[currLen++] = 0;
        char* tmp = addStrings(ans, curr);
        free(ans), free(curr);
        ans = tmp;
    }
    return ans;
}

思路详解

addStrings 函数思路详解

addStrings 函数用于实现两个大整数字符串的加法。其输入是两个表示整数的字符串 num1 和 num2,输出是它们相加后的字符串结果。

步骤分析:
  1. 初始化变量

    • i 和 j 分别初始化为 num1 和 num2 字符串的最后一个字符的索引。
    • add 用于存储进位,初始为 0。
    • ans 是结果字符串的动态分配数组,长度为 i + j + 5 以确保足够存储结果及结束符。
  2. 逐位相加

    • 使用 while 循环,条件是 ij 至少有一个大于等于 0 或者有进位 add
    • 在每次循环中,将 num1[i] 和 num2[j] 转换为对应的整数值 x 和 y,如果已经超出字符串范围则设为 0。
    • 将 xy 和 add 相加,得到当前位的和 result,并将 result % 10 存储到 ans 中,同时更新 add 为 result / 10
  3. 反转结果字符串

    • 因为计算时是从低位到高位进行的,所以需要将结果字符串反转过来。
    • 通过一个循环交换 ans 的前后对应字符。
  4. 转换为字符表示

    • 将结果字符串中的每个数字字符加上 '0',以转换为正确的字符表示。
  5. 添加字符串结束符

    • 在结果字符串的末尾添加字符串结束符 \0
  6. 返回结果

    • 返回结果字符串 ans

multiply 函数思路详解

multiply 函数用于实现两个大整数字符串的乘法。其输入是两个表示整数的字符串 num1 和 num2,输出是它们相乘后的字符串结果。

步骤分析:
  1. 初始化变量

    • m 和 n 分别存储 num1 和 num2 字符串的长度。
    • ans 是结果字符串的动态分配数组,初始为 '0',表示乘积为 0。
  2. 边界情况处理

    • 如果任一字符串长度为 1 且值为 '0',则直接返回结果 ans
  3. 逐位相乘

    • 使用外层循环,逆序遍历 num2 的每一位字符。
    • 对于 num2 的每一位字符,初始化一个临时字符串 curr 用于存储该位的乘积。
    • 内层循环遍历 num1 的每一位字符,计算乘积并存储到 curr 中。
    • 每次乘积可能产生进位,需要处理这些进位。
  4. 处理进位和反转字符串

    • 将 curr 中的数字反转,并转换为字符表示。
  5. 累加乘积

    • 使用 addStrings 函数将当前位的乘积 curr 累加到结果 ans 上。
    • 更新 ans 为新的累加结果。
  6. 返回结果

    • 循环结束后,返回累加的最终结果字符串 ans

以上两个函数都采用了模拟手工计算的方式,逐位处理每一位的加法或乘法,同时考虑进位问题,并通过字符串反转来得到正确的顺序。这种方法的优点是直观且容易理解,但需要注意内存管理和字符串操作的正确性。

知识点精炼

  1. 动态内存分配

    • malloc 函数用于动态分配内存,返回指向分配内存块的指针。
    • 在使用动态分配的内存时,需要确保在不再使用时调用 free 函数释放内存,以避免内存泄漏。
  2. 字符串长度获取

    • strlen 函数用于计算字符串的长度,返回值是字符串中的字符数量,不包括字符串结束符 \0
  3. 字符串反转

    • 通过一个循环交换字符串的前后对应字符,实现字符串的反转。
  4. 字符串相加

    • 将两个字符串中的每一位数字相加,并考虑进位,将结果存储在动态分配的数组中。
  5. 字符串相乘

    • 采用模拟手工计算的方式,逐位相乘并累加,处理进位问题,实现字符串的乘法。
  6. 整数转换为字符串

    • 通过循环,将每个数字字符转换为对应的整数值,并加上字符 '0',以转换为正确的字符表示。
  7. 字符串结束符

    • 在字符串的末尾添加字符串结束符 \0,表示字符串的结束。
  8. 指针的使用

    • 动态分配的内存块通过指针来访问,需要确保指针指向的有效性。
  9. 循环结构

    • 使用 while 循环和 for 循环实现字符串的逐位处理和乘法累加。
  10. 边界条件处理

    • 在函数开始时检查输入字符串的长度和值,以处理边界情况,如其中一个字符串长度为 1 且值为 '0'

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值