LeetCode 43. 字符串相乘 Multiply Strings(C语言)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hang404/article/details/85165660

题目描述:

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

示例 1:

输入: num1 = “2”, num2 = “3”
输出: “6”

示例 2:

输入: num1 = “123”, num2 = “456”
输出: “56088”

说明:

  1. num1 和 num2 的长度小于110。
  2. num1 和 num2 只包含数字 0-9。
  3. num1 和 num2 均不以零开头,除非是数字 0 本身。
  4. 不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。

题目解答:

方法1:暴力法

取字符串2的每一个字符与字符串1相乘,计算其结果,并将其依次累加,得到其乘积,但较复杂。
运行时间8ms,代码如下。

void multi(char* num, int t, int len, char* temp) {
    if(t == 0) {
        temp[0] = 0;
        return;
    }
    int i = 0, flag = 0, tmp = 0, j = 0;
    for(i = len - 1; i >= 0; i--) {
        tmp = (num[i] - '0') * t + flag;
        if(tmp >= 10) {
            flag = tmp / 10;
            temp[j++] = '0' + (tmp % 10);
        }
        else {
            flag = 0;
            temp[j++] = '0' + tmp;
        }   
    }
    temp[j] = flag ? (flag + '0') : 0;
    return;
}
void reverse(char* s, int len) {
    int i = 0;
    char t = 0;
    for(i = 0; i < len / 2; i++) {
        t = s[i];
        s[i] = s[len - 1 - i];
        s[len - 1 - i] = t;
    }
}
char* multiply(char* num1, char* num2) {
    char* result = (char*)calloc(220, sizeof(char));
    char* temp = (char*)calloc(220, sizeof(char));
    char* temp2 = (char*)calloc(220, sizeof(char));
    result[0] = '0';
    if(num1 == NULL || num2 == NULL || num1[0] == '0' || num2[0] == '0')
        return result;
    int l1 = strlen(num1);
    int l2 = strlen(num2);
    int i = 0, t = 0, j = 0, l = 0, k = 0, flag = 0;
    for(i = l2 - 1; i >= 0; i--) {
        for(j = 0; j < l2 - 1 - i; j++)
            temp[j] = '0';
        multi(num1, num2[i] - '0', l1, temp + j);
        j = 0;
        k = 0;
        l = 0;
        while(temp[j] || result[k] || flag) {
            t = flag;
            if(result[k]) 
                t += (result[k++] - '0');
            if(temp[j])
                t += (temp[j++] - '0');
            if(t >= 10)
                flag = t / 10;
            else
                flag = 0;
            temp2[l++] = ('0' + t % 10);
        }
        temp2[l] = 0;
        memcpy(result, temp2, (l + 1) * sizeof(char));
    }
    reverse(result, l);
    free(temp);
    free(temp2);
    return result;
}

方法2:每位的数字

分别取两个字符串中的某位数字,直接将其结果存放在乘积的对应位置上,如12*341*42 * 3都会存在第二位上,对他们求和,后边再操作进位即可。
运行时间4ms,代码如下。

char* multiply(char* num1, char* num2) {
    int* sum = (int*)calloc(220, sizeof(int));
    if(num1 == NULL || num2 == NULL || num1[0] == '0' || num2[0] == '0') {
        char* result = (char*)calloc(2, sizeof(char));
        result[0] = '0';
        return result;
    }
    int l1 = strlen(num1);
    int l2 = strlen(num2);
    int i = 0, j = 0, t = 0, index = 0;
    for(i = 0; i < l1; i++) {
        for(j = 0; j < l2; j++) {
            sum[i + j] += (num1[i] - '0') * (num2[j] - '0');
        }
    }
    for(i = l1 + l2 - 2; i >= 0; i--) {
        sum[i] += t;
        if(sum[i] >= 10) {
            t = sum[i] / 10;
            sum[i] = sum[i] % 10;
        }
        else
            t = 0;
    }
    int len = 2 + (t ? l1 + l2 - 1 : l1 + l2 - 2);
    char* result = (char*)malloc(len * sizeof(char));
    if(t)
        result[index++] = '0' + t;
    for(i = 0; i <= l1 + l2 - 2; i++)
        result[index++] = sum[i] + '0';
    result[index] = 0;
    free(sum);
    return result;
}

猜你喜欢

转载自blog.csdn.net/hang404/article/details/85165660