用C++的分治算法,写一段大整数乘法的代码,并分析算法性能与复杂度
时间: 2023-05-11 15:05:46 浏览: 123
好的,以下是使用C的分治算法实现大整数乘法的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 1000
void add(char *a, char *b, char *res) {
int len_a = strlen(a), len_b = strlen(b);
int len_res = len_a > len_b ? len_a : len_b;
int carry = 0;
for (int i = 0; i < len_res; i++) {
int num_a = i < len_a ? a[len_a - i - 1] - '0' : 0;
int num_b = i < len_b ? b[len_b - i - 1] - '0' : 0;
int sum = num_a + num_b + carry;
res[len_res - i - 1] = sum % 10 + '0';
carry = sum / 10;
}
if (carry) {
res[0] = carry + '0';
}
}
void sub(char *a, char *b, char *res) {
int len_a = strlen(a), len_b = strlen(b);
int len_res = len_a > len_b ? len_a : len_b;
int borrow = 0;
for (int i = 0; i < len_res; i++) {
int num_a = i < len_a ? a[len_a - i - 1] - '0' : 0;
int num_b = i < len_b ? b[len_b - i - 1] - '0' : 0;
int diff = num_a - num_b - borrow;
if (diff < 0) {
diff += 10;
borrow = 1;
} else {
borrow = 0;
}
res[len_res - i - 1] = diff + '0';
}
}
void multiply(char *a, char *b, char *res) {
int len_a = strlen(a), len_b = strlen(b);
if (len_a == 0 || len_b == 0) {
res[0] = '0';
res[1] = '\0';
return;
}
if (len_a == 1 && len_b == 1) {
int num_a = a[0] - '0', num_b = b[0] - '0';
int prod = num_a * num_b;
if (prod == 0) {
res[0] = '0';
res[1] = '\0';
return;
}
res[0] = prod / 10 + '0';
res[1] = prod % 10 + '0';
res[2] = '\0';
return;
}
int len = len_a > len_b ? len_a : len_b;
if (len % 2 == 1) {
len++;
}
char *a1 = (char *)malloc((len / 2 + 1) * sizeof(char));
char *a2 = (char *)malloc((len / 2 + 1) * sizeof(char));
char *b1 = (char *)malloc((len / 2 + 1) * sizeof(char));
char *b2 = (char *)malloc((len / 2 + 1) * sizeof(char));
char *a1b1 = (char *)malloc((2 * len / 2 + 1) * sizeof(char));
char *a2b2 = (char *)malloc((2 * len / 2 + 1) * sizeof(char));
char *ab = (char *)malloc((2 * len / 2 + 1) * sizeof(char));
char *temp = (char *)malloc((2 * len / 2 + 1) * sizeof(char));
memset(a1, '0', (len / 2 + 1) * sizeof(char));
memset(a2, '0', (len / 2 + 1) * sizeof(char));
memset(b1, '0', (len / 2 + 1) * sizeof(char));
memset(b2, '0', (len / 2 + 1) * sizeof(char));
memset(a1b1, '0', (2 * len / 2 + 1) * sizeof(char));
memset(a2b2, '0', (2 * len / 2 + 1) * sizeof(char));
memset(ab, '0', (2 * len / 2 + 1) * sizeof(char));
memset(temp, '0', (2 * len / 2 + 1) * sizeof(char));
for (int i = 0; i < len / 2; i++) {
a1[i] = i < len_a - len / 2 ? a[i] : '0';
a2[i] = i >= len_a - len / 2 ? a[i] : '0';
b1[i] = i < len_b - len / 2 ? b[i] : '0';
b2[i] = i >= len_b - len / 2 ? b[i] : '0';
}
multiply(a1, b1, a1b1);
multiply(a2, b2, a2b2);
add(a1, a2, temp);
add(b1, b2, ab);
multiply(temp, ab, temp);
sub(temp, a1b1, temp);
sub(temp, a2b2, temp);
for (int i = 0; i < 2 * (len / 2); i++) {
res[i] = i < len / 2 ? a1b1[i] : a2b2[i - len / 2];
}
add(res, temp, temp);
for (int i = 0; i < 2 * (len / 2); i++) {
res[i + len / 2] = temp[i];
}
free(a1);
free(a2);
free(b1);
free(b2);
free(a1b1);
free(a2b2);
free(ab);
free(temp);
}
int main() {
char a[MAX_LEN], b[MAX_LEN], res[MAX_LEN * 2];
scanf("%s%s", a, b);
multiply(a, b, res);
printf("%s\n", res);
return 0;
}
这个算法的时间复杂度为O(n^log2(3)),其中n为两个大整数的位数。这个复杂度比传统的竖式乘法的O(n^2)要好很多,因此在处理大整数乘法时,分治算法是一个非常好的选择。
相关推荐


















