我想找到可以表示为GCD为1的整数的最大数字对,以下是我的代码,但它太慢而且可能很愚蠢。你有更好的主意吗?如何实现呢?
#include <stdio.h>
int gcd(int u, int v)
{
while (u > 0) {
if (u < v) {
int t = u;
u = v;
v = t;
}
u = u - v;
}
return v;
}
int main()
{
int u, v;
u = v = ~(1 << (sizeof(int) * 8 - 1));
while (u > 0) {
if (gcd(u, v) == 1) {
printf("%d %d\n", u, v);
break;
}
--u;
}
}
答案 0 :(得分:2)
您的代码存在多个问题:
您使用的是int
类型,但可能会有更大的整数类型可以产生更大的对:unsigned int
,unsigned long
,unsigned long long
...问题规范必须更加精确。
表达式~(1 << (sizeof(int) * 8 - 1))
导致未定义的行为,因为中间值1 << (sizeof(int) * 8 - 1)
导致算术溢出。另请注意,某些稀有系统上的字节可能超过8位。使用INT_MAX
中定义的<limits.h>
可获得更好的便携性。
您没有枚举所有值对:在32位系统上,您会找到最大的int
对,但对于INT_MAX
与2147483647不同的另一个系统,您可能会错过最大金额的那对。
你gcd()
函数,原始的欧几里德方法,效率非常低。您应该使用基于模数的版本,例如:
int gcd(int a, int b) {
while (b != 0) {
int t = b;
b = a % b;
a = t;
}
return a;
}
最后,很明显,对于大于n
,0
的任何整数gcd(n, n + 1) == gcd(n, 1) == 1
。因此,您的问题很简单,解决方案是最大的整数及其前身。
因此最大的便携式对是:
#include <limits.h>
#include <stdio.h>
int main(void) {
printf("%llu %llu\n", ULLONG_MAX, ULLONG_MAX - 1);
return 0;
}