该程序对C中的数字进行素数分解。
#include <stdio.h>
int main(void) {
int number, i, p, n, factors, count;
int numbers[1000000];
int counter = 0;
char text[100000];
for (count = 0; count < 1000000; count++) {
fgets(text, 10000000, stdin);
if (sscanf(text, "%d", &number) == 1) {
if (number == 0)
break;
numbers[count] = number;
} else {
numbers[count] = 0;
}
}
counter = 0;
for (i = 0; i < count; i++) {
if ((numbers[i] < 0) || (numbers[i] == 0)) {
fprintf(stderr, "Error: Wrong Input!\n");
return 100;
break;
}
number = numbers[i];
printf("Prime factorization of nubmer %d is:\n", number);
factors = 0;
for (p = 2; p * p <= number; p += 1 + (p & 1)) {
if (number % p == 0) {
n = 0;
factors++;
do {
number /= p;
n++;
} while (number % p == 0);
if (n == 1) {
printf("%d ", p);
++counter;
} else
printf("%d^%d ", p, n);
++counter;
if (count > 0 && number != 1)
printf("x ");
}
}
if (factors == 0 || number != 1)
printf("%d", number);
printf("\n");
}
return 0;
}
此程序适用于小于10 8 的数字。但我的问题是,如果有一种方法可以使这个程序甚至对于像10 12 这样的数字。我知道int不够,但是当我尝试使用long int时,它没有用。我也听说过malloc的一些内容,但我一直未能实现(理解)它。
答案 0 :(得分:1)
对大数字进行因子分解通常需要比简单的试验分割更微妙的方法。这是一个可能的大纲方法:
答案 1 :(得分:0)
你可以使用很长时间。但是,真正的问题可能是,需要花费很长时间对数字进行因子分解,而这些因素并不适合普通的数据。例如。你试图将10 ^ 12范围内的素数分解,那么你将不得不做大约10 ^ 6个分数。
关于malloc的事情根本不会帮助你解决这个问题,因为更大的价值观需要更长的时间来分解。所以,如果你想知道malloc是如何工作的,我建议为此开一个单独的问题。
答案 2 :(得分:0)
以下是使用unsigned long long
对代码进行的返工。 (我抛出文件的东西,以保持这个最小的例子。)这是否适用于您的目的取决于您的系统如何定义long long
(在我的系统上它的64位)。我还重新编写了输出格式以兼容Unix dc
命令的后缀表示法,因此我可以轻松检查结果是否正确:
#include <stdio.h>
#include <stdlib.h>
int main() {
unsigned long long large = 18446744073709551615ULL; // 2^64 - 1
for (unsigned long long counter = large - 1000; counter < large; counter++) {
unsigned long long number = counter;
printf("Prime factorization of %llu is:", number);
unsigned long factors = 0;
for (unsigned long long p = 2; p * p <= number; p += 1 + (p & 1)) {
if (number % p == 0) {
factors++;
unsigned long n = 0;
do {
number /= p;
n++;
} while (number % p == 0);
if (n == 1) {
printf(" %llu", p);
}
else {
printf(" %llu %lu ^", p, n);
}
if (number != 1 && factors > 1) {
printf(" *");
}
}
}
if (factors == 0 || number != 1) {
factors++;
printf(" %llu", number);
}
if (factors > 1) {
printf(" *");
}
printf("\n");
}
return 0;
}
SAMPLE OUTPUT
% ./a.out
Prime factorization of 18446744073709550615 is: 5 563 * 751 * 8725722280871 *
Prime factorization of 18446744073709550616 is: 2 3 ^ 3 * 41 * 7523 * 8243 * 14479 * 20879 *
Prime factorization of 18446744073709550617 is: 79 557 * 419215600611539 *
Prime factorization of 18446744073709550618 is: 2 2298974999 * 4011949691 *
Prime factorization of 18446744073709550619 is: 3 3 ^ 1008659 * 677347590683 *
Prime factorization of 18446744073709550620 is: 2 2 ^ 5 * 7 * 149 * 233 * 3795329598449 *
Prime factorization of 18446744073709550621 is: 11 23 * 72912031911895457 *
Prime factorization of 18446744073709550622 is: 2 3 * 479909 * 6406334004193 *
Prime factorization of 18446744073709550623 is: 3421377637 5391612979 *
Prime factorization of 18446744073709550624 is: 2 5 ^ 61 * 593 * 1699 * 9379762391 *
Prime factorization of 18446744073709550625 is: 3 5 4 ^ * 13 * 756789500459879 *
Prime factorization of 18446744073709550626 is: 2 3743461 * 2463862195133 *
Prime factorization of 18446744073709550627 is: 7 1283 * 4339 * 627089 * 754877 *
Prime factorization of 18446744073709550628 is: 2 2 ^ 3 2 ^ * 101 * 293 * 42751 * 405025111 *
Prime factorization of 18446744073709550629 is: 17 43 * 613 * 66457 * 619442699 *
...
这样运行速度较慢但合理。您可以通过将unsigned long long
替换为某些编译器支持的uint128_t
来在某些系统上进一步推动这一点:
typedef unsigned __int128 uint128_t;
(然后将unsigned long
声明提升至unsigned long long
。)您需要为uint128_t
类型提供数字打印例程printf()
isn&#39;我会直接处理它们。我用上面的代码尝试了这个并且它有效:
Prime factorization of 340282366920938463426481119284349108124 is: 2 2 ^ 31 * 6131 * 7654271 * 21163829 * 21491837 * 128562653437 *
% dc
2 2 ^ 31 * 6131 * 7654271 * 21163829 * 21491837 * 128562653437 * p
340282366920938463426481119284349108124
但我在运行它时从未看到它完成多个数字!
答案 3 :(得分:0)
对unsigned long long
使用number
类型,素数因子将以更长的计算时间为您带来10 19 。
但请注意,定义具有自动存储的大型本地阵列可能会导致问题,尤其是当它达到8 MB的大小时,类型为unsigned long long
的情况(此类型至少为64位宽) 。从堆中分配它更安全。
以下是代码的改编版本:
#include <stdio.h>
#include <stdlib.h>
#define NUMBER_MAX 1000000
int main(void) {
unsigned long long *numbers;
unsigned long long number, p;
int i, n, factors, count;
char text[100];
numbers = calloc(NUMBER_MAX, sizeof(*numbers));
if (numbers == NULL) {
printf("cannot allocate number array\n");
return 1;
}
for (count = 0; count < NUMBER_MAX; count++) {
if (!fgets(text, sizeof text, stdin)) {
break;
}
if (sscanf(text, "%llu", &number) == 1 && number > 0) {
numbers[count] = number;
} else {
fprintf(stderr, "Error: Wrong Input!\n");
return 100;
}
}
for (i = 0; i < count; i++) {
number = numbers[i];
printf("Prime factorization of nubmer %llu is:\n", number);
factors = 0;
for (p = 2; p < 0x100000000 && p * p <= number; p += 1 + (p & 1)) {
if (number % p == 0) {
n = 0;
factors++;
do {
number /= p;
n++;
} while (number % p == 0);
if (n == 1) {
printf("%llu ", p);
} else {
printf("%llu^%d ", p, n);
}
if (number != 1) {
printf("* ");
}
}
}
if (factors == 0 || number != 1) {
printf("%llu", number);
}
printf("\n");
}
free(numbers);
return 0;
}