Leetcode c语言-Multiply Strings

Title:

Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2.

Note:

  1. The length of both num1 and num2 is < 110.
  2. Both num1 and num2 contains only digits 0-9.
  3. Both num1 and num2 does not contain any leading zero.
  4. 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选择最小的作为判断条件。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值