Title:
Given two non-negative integers num1
and num2
represented as strings, return the product of num1
and num2
.
Note:
- The length of both
num1
andnum2
is < 110. - Both
num1
andnum2
contains only digits0-9
. - Both
num1
andnum2
does not contain any leading zero. - You must not use any built-in BigInteger library or convert the inputs to integer directly.
题目大意很容易懂,实现两个字符串类型的整数相乘。
解题思路:假设第一数长为m,第二个数长为n,那么相乘的数大小为m+n-1或者m+n(有进位的情况),那么对于某一位i,需要对所有能够两两组合为i的位相乘,也就是1和i-1,2和i-2,3和i-3等。然后两两相乘的结果再相加,相加的结果个位就是i位的结果,十位则表示有进位,留给下一位计算。
举个例子:
12*24=288,m=2,n=2,相乘数大小为m+n-1(没有进位),那么对于结果的第0位,也就是个位,只有一种组合方式就是0=0+0,因此只需要将两个数的个位相乘即可,2*4=8,没有进位。对于结果第一位,也就是十位,有两种组合方式,1=0+1=1+0,也就是两个数的个位和十位分别和对方的十位和个位相乘再相加,2*2+1*4=8,没有进位。结果第三位,百位,只有一种,2=1+1,1*2=2。
在解题过程中会碰到一些问题,比如a[2]="89",那么a[0]表示的是高位(十位)8,a[1]表示的低位(个位)9,这个对应关系在具体编程时需要注意。可能需要进行转换。
还有对于进位的情况,可能有进位,也可能没进位,为了方便起见,在嵌套循环时一律按照没有进位考虑,也就是i<len1+len2-1,注意这里i从0开始取,所以是<不是<=。
solution:
char* multiply(char* num1, char* num2) {
int len1=0;
int len2=0;
int i,j;
int num=0;
int m;
char temp;
char *result=(char*)malloc(sizeof(char)*1000000);
if (num1==NULL || num2==NULL)
return "";
while (num1[len1]) {
len1++;
}
if (len1==1 && num1[0]=='0')
return "0";
while (num2[len2]) {
len2++;
}
if (len2==1 && num2[0]=='0')
return "0";
for (i=0;i<len1+len2-1;i++) {
for (j=0;j<=(i<(len1-1)?i:(len1-1));j++) {
if (i-j<len2) {
/*这里的len1-1-j和len2-1-(i-j)表示反转,比如a[2]="98",那么a[0]=9,a[1]=8
而相乘的话,则是从a[1]开始,因为a[1]是个位,因此这里j表示,从a的左边开始
a[0],a[1]等,而len1-1-j表示从右边开始,也就是a[1],a[0]*/
num=num+(num1[len1-1-j]-'0')*(num2[len2-1-(i-j)]-'0');
}
}
if (i!=len1+len2-1 || num>0) {
result[i]=num%10+'0';
}
num=num/10;
}
/*这里是对最高一位的进位进行表示,比如98*99=9604,在上面循环中,num=num/10结果是最高位9,
但没有加入到result中就直接跳出了,因此在这里加上,并且要注意一点,这里跳出后的i是已经加了1的,
在循环for (i=0;i<len1+len2-1;i++)条件中,i<len1+len2-1,因此i要==len1+len2-1才能够跳出循环,
因此跳出后的i=len1+len2-1。而不是<len1+len2-1,因此下面的result[i]=num+'0';直接用i而不是i+1*/
if (i==len1+len2-1 && num>0) {
result[i]=num+'0';
/*这里的i++,是为下面的倒序做准备,i++后,表明了i表示的是个数,比如i为1,
result[1]=9,那么总共有两位,因此i++表示两位,在倒序时,m<i/2*/
i++;
}
/*这里对结果进行倒序,因为是由低到高放入result的,因此result[0]是最低位,因此要倒序,将result[0]变为最高位数字*/
for (m=0;m<(i)/2;m++) {
temp=result[m];
result[m]=result[i-m-1];
result[i-m-1]=temp;
}
return result;
}
还有要注意的一点是, for (j=0;j<=(i<(len1-1)?i:(len1-1));j++) 。这个循环的条件是选取i和len1-1中最小的作为判断条件,这里的j表示的是第一个数的第j位,j不会大于len1-1也就是第一个数的长度-1的位,也不能大于i,因为i-j表示的第二个数的位数,是肯定要>=0的。因此j选择最小的作为判断条件。