我需要一种有效的算法来计算乘以2个大数的结果(每个最多10000个数字)。 我已经编写了一个代码但它在判断时超出了时间限制。 我使用字符串扫描了数字,然后使用基本的乘法方法,将结果存储在整数数组中:
#include <stdio.h>
int main() {
int n, i, j, k, c, m, r, x, t, h, y;
scanf("%d", &n); // no of test cases
for (i = 0; i < n; i++) {
char A[10002], B[10002];
int c1 = 0, c2 = 0, l;
scanf("%s %s", A, B); //scanning the no.s
for (j = 0; A[j] != '\0'; j++)
c1++;
for (j = 0; B[j] != '\0'; j++)
c2++;
l = 29999;
int a[30002] = { 0 };
for (j = c2 - 1; j >= 0; j--) {
c = 0;
x = l - 1;
for (k = c1 - 1; k >= 0; k--) {
h = (int)B[j] - 48;
y = (int)A[k] - 48;
r = (h * y) + c; //multiply the last digit of B with all the digits of A.
m = r % 10;
r = r / 10; c = r; //c is the carry
a[x] = m + a[x];
if (a[x] > 9) {
a[x] = a[x] % 10;
a[x - 1] = a[x - 1] + 1; //adding 1 to previous posn of result in case of overflow.since only maximum 1 can be the 1st digit.
}
x--;
}
l--;
a[x] = a[x] + c;
}
int flag = 0;
for (k = 0; k <= 29998; k++) {
if (a[k] != 0) {
printf("%d", a[k]);
flag = 1;
} else if (a[k] == 0 && flag == 1)
printf("0");
}
if (flag == 0)
printf("0");
printf("\n");
}
return 0;
}
答案 0 :(得分:6)
请勿逐位操作数字!如果你只是将它们分成9个数字的组,而不是10000x10000,你将它减少到1111x1111,这应该快大约80倍。 (这假设您的平台具有32位整数。)
答案 1 :(得分:0)
检查一下(前提是你输入的两个数字是整数而不是字符串)!
#include<stdio.h>
int main()
{
int n,m,j,temp,i,c;
int a[2000000];
a[0]=1;j=0;
printf("Enter the first number: ");
scanf("%d",&m);
printf("Enter the second number: ");
scanf("%d",&n);
for(i=0;i<=j;i++)
{
temp=(a[i]*m)+temp;
a[i]=temp%10;
temp=temp/10;
}
while(temp>0)
{
a[++j]=temp%10;
temp=temp/10;
}
for(i=0;i<=j;i++)
{
temp=(a[i]*n)+temp;
a[i]=temp%10;
temp=temp/10;
}
while(temp>0)
{
a[++j]=temp%10;
temp=temp/10;
}
for(i=j;i>=0;i--)
printf("%d",a[i]);
return 0;
}
答案 2 :(得分:0)
以下是结合了两种有效技术的解决方案:
1000000
的结果。代码如下:
#include <stdio.h>
#include <string.h>
#include <time.h>
#define NDIGITS 6
int main() {
char A[10002], B[10002];
int aa[10000 / NDIGITS + 1];
int bb[10000 / NDIGITS + 1];
int cc[10000 / NDIGITS + 1 + 10000 / NDIGITS + 1];
int n, na, nb, nc, i, j, c;
if (scanf("%d", &n) != 1) // no of test cases
return 1;
static int const m10[10] = {
1, 10, 100, 1000, 10000, 100000, 1000000,
10000000, 100000000, 1000000000 };
while (n-- > 0 && scanf("%10000s %10000s", A, B) == 2) {
for (na = 0, c = j = 0, i = strlen(A); i-- > 0;) {
c += (A[i] - '0') * m10[j];
if (++j == NDIGITS || i == 0) {
aa[na++] = c;
c = j = 0;
}
}
for (nb = 0, c = j = 0, i = strlen(B); i-- > 0;) {
c += (B[i] - '0') * m10[j];
if (++j == NDIGITS || i == 0) {
bb[nb++] = c;
c = j = 0;
}
}
nc = na + nb; // max length of A*B
// initialize result array
for (i = 0; i < nc; i++)
cc[i] = 0;
for (i = 0; i < na; i++) {
long long m = 0;
for (j = 0; j < nb; j++) {
m += cc[i + j] + (long long)aa[i] * bb[j];
cc[i + j] = m % m10[NDIGITS];
m /= m10[NDIGITS];
}
cc[i + j] += m;
}
for (i = nc; i-- > 0 && cc[i] == 0;)
continue;
printf("%d", cc[i]);
while (i-- > 0)
printf("%0*d", NDIGITS, cc[i]);
printf("\n");
}
return 0;
}
答案 3 :(得分:-2)
使用break;
走出最外层的for循环就可以了。