大整数相乘
描述:
num1
和num2
是非负整数
的字符串
表示形式,获取他俩的乘积,结果用字符串表示。
输入限制:
- 1 <= num1.length, num2.length <= 200
- num1 和 num2 只包含数字.
- 除0之外 num1 和 num2 不以0开头.
分析过程:
1 2 3
X 4 5 6
——————————
7 3 8
6 1 5
4 9 2
———————————
5 6 0 8 8
如上,num1为123,num2为456,按照习惯,我们按照列竖式的方法,从个位往前算,首先观察3X6,反映在结果56088中下标为4,
因为两数乘积的最大长度为这两个数的长度和,因此,我们下标要加上1,结果8要保存在字符串的下标5处。
#define STR_LEN 256
static char res[STR_LEN];
char * multiply(char * num1, char * num2){
int len1 = strlen(num1);
int len2 = strlen(num2);
if (len1 == 0 || len2 == 0) return "0";
if (*num1 =='0' || *num2 =='0') return "0";
memset(res, '0', STR_LEN);
for (int i = len1 - 1; i >= 0; i--) {
for (int j = len2 - 1; j >= 0; j--) {
int index = i + j + 1;
int mul = (num1[i] - '0') * (num2[j] - '0');
int sum = mul + res[index] - '0';
int cur = sum % 10;
int inc = sum / 10;
res[index] = cur + '0';
res[index - 1] += inc;
}
}
res[len1 + len2] = 0;
if (res[0] == '0') return &res[1];
return res;
}
当然,从前往后遍历也是可以的,上述代码只需稍加修改即可。后面相乘的数累加到前面的数字上,如有进位,需要再向前加,直到没有进位,递归终止。实际上在运算中,也发生了类似从低到高的过程,增加了运算量,因此推荐上述常规的做法,没有递归,逻辑较为清晰简单,符合习惯。
#define STR_LEN 256
static char res[STR_LEN];
void add_to_string(char *string, char num, int index) {
if (index < 0) return;
int sum = string[index] - '0' + num;
int cur = sum % 10;
int inc = sum / 10;
string[index] = cur +'0';
if (inc)
add_to_string(string, inc, --index);
}
char * multiply(char * num1, char * num2){
int len1 = strlen(num1);
int len2 = strlen(num2);
if (len1 == 0 || len2 == 0) return "0";
if (*num1 =='0' || *num2 =='0') return "0";
memset(res, '0', STR_LEN);
for (int i = 0; i < len1; i++) {
for (int j = 0; j < len2; j++) {
int index = i + j + 1;
int mul = (num1[i] - '0') * (num2[j] - '0');
int cur = mul % 10;
int inc = mul / 10;
add_to_string(res, cur, index);
if (inc)
add_to_string(res, inc, --index);
}
}
res[len1 + len2] = 0;
if (res[0] == '0' || res[0] == 0) return &res[1];
return res;
}