3 2 1
x 4 3
_______
9 6 3
1 2 8 4
_______
1 3 8 0 3
注意:
-
m位的数字乘以n位的数字的结果最大为m+n位:
99999 < 1000100 = 100000,最多为3+2 = 5位数。 -
先将字符串逆序便于从最低位开始计算。
-
首先要注意num1[i] * num2[j]的结果应该加到ret[i+j]的位置上。
-
最容易遗漏的corner case 如999*0 = 0000,此时需要去掉开始的0,但又需要保留最后一个0。
3, char * ret = calloc(len1+len2+1, sizeof(char));
for(int k = 0; k < len1+len2; k++)
ret[k] = '0';
申请完保存结果的数组后,需要初始化为'0', 对应的ascii 48, 而不是0。
4,进位只用在内层循环内,外围循环开头需要carry置零
5,保存每次的返回结果值需要记住是字符形式的数字 需要结果上面加'0'
ret[i+j] = carry%10+'0';
6, 当循环检测开头的零并删除的时候,要记住遇见零就返回 (ret[m] == '0') 需要放在for判断条件里面里面 而不应该在for循环内部。
for(int m = 0; m < len1+len2-1 && (ret[m] == '0'); m++)
index++;
void reverse(char *a, int left, int right)
{
while(left < right){
char tmp = a[left];
a[left] = a[right];
a[right] = tmp;
left++;
right--;
}
}
char* multiply(char* num1, char* num2) {
if(num1 == NULL || num2 == NULL)
return NULL;
int len1 = strlen(num1);
int len2 = strlen(num2);
reverse(num1, 0, len1-1);
reverse(num2,0, len2-1);
char * ret = calloc(len1+len2+1, sizeof(char));
for(int k = 0; k < len1+len2; k++)
ret[k] = '0';
int i = 0;
int j = 0;
int carry = 0;
int val ;
for(i = 0; i < len2; i++){
carry = 0;
val = num2[i] - '0';
for(j = 0; j < len1; j++){
carry += ret[i+j]-'0'+val*(num1[j]-'0');
ret[i+j] = carry%10+'0';
carry = carry/10;
}
if(carry)
ret[i+len1] = carry+'0';
}
reverse(ret, 0, len1+len2-1);
ret[len1+len2] = 0;
int index = 0;
for(int m = 0; m < len1+len2-1 && (ret[m] == '0'); m++)
index++;
ret += index;
return ret;
}
网友评论