给定两个以字符串形式表示的非负整数 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本身。
思路:
1. 确定结果的长度:
两个非负整数 num1 和 num2 相乘,结果的最大位数为 num1 的长度加上 num2 的长度。例如, 99 和 99 相乘结果是 9801 , 99 长度为 2,相乘结果长度为 4。所以可以根据这个规律先为结果分配足够的空间。
2. 模拟乘法运算:
采用类似于竖式乘法的方式。对于 num1 的每一位数字,乘以 num2 的每一位数字,然后将结果累加到对应的位置上。例如,计算 12 和 34 相乘, 2 * 4 = 8 , 2 * 3 = 6 , 1 * 4 = 4 , 1 * 3 = 3 ,这些结果会根据它们的位置进行累加。在代码实现中, num1[i] 与 num2[j] 相乘的结果应该累加到 result[i + j + 1] 位置上(因为 i 和 j 是从字符串末尾开始遍历的)。
3. 处理进位:
在完成所有位的乘法和累加后,需要处理每一位的进位情况。从结果数组的最后一位开始(最低位),如果当前位的值大于等于 10,则将其除以 10 的商累加到前一位,当前位保留除以 10 的余数。
4. 生成最终结果字符串:
处理完进位后,跳过结果数组前面的 0(但不能跳过唯一的 0),将数组中的每一位数字转换为字符,存储到结果字符串中,并添加字符串结束符 '\0' 。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// 函数功能:实现两个字符串形式的数字相乘
char* multiply(char* num1, char* num2) {
// 获取字符串num1的长度
int length1 = strlen(num1);
// 获取字符串num2的长度
int length2 = strlen(num2);
// 计算相乘后结果字符串的总有效位数(理论上最大位数为两数长度之和)
int totalLength = length1 + length2;
// 定义索引变量,用于遍历字符数组
int charIndex = 0;
// 定义索引变量,用于遍历保存中间计算结果的数组
int valueIndex = 0;
// 分配内存,用于存储中间计算结果(每个元素对应一位数字的计算结果)
int *value = (int *)malloc(sizeof(int) * totalLength);
// 将value数组所有元素初始化为0
memset(value, 0, sizeof(int) * totalLength);
// 分配内存,用于存储最终的结果字符串(+1是为了存储字符串结束符'\0')
char *result = (char *)malloc(sizeof(char) * (totalLength + 1));
// 逐位相乘并累加结果到value数组中
for(int i = length1 - 1; i >= 0; i--) {
for(int j = length2 - 1; j >= 0; j--) {
// 将字符转换为数字并相乘,累加到对应位置上
value[i + j + 1] += (num1[i] - '0') * (num2[j] - '0');
}
}
// 处理进位,从低位向高位遍历
for(int i= totalLength - 1; i > 0; i--) {
// 将当前位的进位累加到前一位
value[i - 1] += value[i] / 10;
// 当前位保留个位数字
value[i] %= 10;
}
// 跳过结果数组前面多余的0,但不能跳过最高位的0(如果是唯一的一位0)
while(value[valueIndex] == 0 && valueIndex < totalLength -1 ) {
valueIndex++;
}
// 将结果数组中的数字转换为字符存储到result字符串中
while(valueIndex < totalLength) {
result[charIndex++] = value[valueIndex++] + '0';
}
// 添加字符串结束符
result[charIndex] = '\0';
// 返回结果字符串
return result;
}
实验小结:
本次实验聚焦于实现两个以字符串形式表示的非负整数相乘,且不能借助内置大数库或直接转为整数。实验过程中,先根据两数长度确定结果最大长度并分配内存。通过模拟竖式乘法,逐位相乘并累加结果到对应位置,完成初步计算。之后处理每一位的进位情况,保证结果的正确性。最后,跳过结果数组前导零,将数字转为字符生成结果字符串。实验成功达成目标,在处理大整数乘法上,该方法有效且符合限制条件,能处理长度在1到200之间的输入,为解决类似高精度计算问题提供了实践思路。