用C++语言,写出代码实现分治法实现两个n位整数的乘法,并分析该算法的时间复杂度。
时间: 2024-05-12 19:16:36 浏览: 122
利用分治法设计一个计算两个n位的大整数相乘的算法,要求计算时间低于O(n2)。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void add(int *a, int *b, int n) { // 高精度加法
int carry = 0;
for (int i = 0; i < n; i++) {
carry += a[i] + b[i];
a[i] = carry % 10;
carry /= 10;
}
}
void sub(int *a, int *b, int n) { // 高精度减法
int borrow = 0;
for (int i = 0; i < n; i++) {
a[i] -= borrow + b[i];
if (a[i] < 0) {
a[i] += 10;
borrow = 1;
} else {
borrow = 0;
}
}
}
void mul(int *a, int *b, int n, int *c) { // 高精度乘法
for (int i = 0; i < n; i++) {
int carry = 0;
for (int j = 0; j < n; j++) {
carry += a[i] * b[j] + c[i + j];
c[i + j] = carry % 10;
carry /= 10;
}
c[i + n] = carry;
}
}
void karatsuba(int *a, int *b, int n, int *c) { // Karatsuba算法
if (n <= 32) { // 递归边界
mul(a, b, n, c);
return;
}
int m = n / 2;
int *x1 = a, *x2 = a + m, *y1 = b, *y2 = b + m;
int *z0 = c, *z1 = c + n, *z2 = c + n + m;
memset(z1, 0, m * 2 * sizeof(int));
karatsuba(x1, y1, m, z0); // 计算z0
karatsuba(x2, y2, m, z2); // 计算z2
add(x1, x2, m); add(y1, y2, m);
karatsuba(x1, y1, m, z1); // 计算z1
sub(z1, z0, n); sub(z1, z2, n);
}
int main() {
char s1[1005], s2[1005];
scanf("%s%s", s1, s2);
int n = strlen(s1), m = strlen(s2);
int len = 1;
while (len < n + m) len <<= 1; // 确定多项式的次数
int *a = (int*)calloc(len, sizeof(int));
int *b = (int*)calloc(len, sizeof(int));
int *c = (int*)calloc(len * 2, sizeof(int));
for (int i = 0; i < n; i++) a[i] = s1[n - 1 - i] - '0';
for (int i = 0; i < m; i++) b[i] = s2[m - 1 - i] - '0';
karatsuba(a, b, len, c);
int k = len * 2 - 1;
while (k > 0 && c[k] == 0) k--;
for (int i = k; i >= 0; i--) printf("%d", c[i]);
printf("\n");
free(a); free(b); free(c);
return 0;
}
```
时间复杂度:设n为两个整数的位数,则Karatsuba算法的时间复杂度为$T(n)=3T(n/2)+O(n)$,其中$O(n)$表示高精度加减乘的时间复杂度。根据主定理,可得$T(n)=O(n^{1.585})$。
阅读全文