下面的程序会计算出可以被1到20之间的所有数字整除的最小正数。您可以在两者中选择哪一个,为什么? 第一段代码:
#include <stdio.h>
#define ulong unsigned long
int main(void)
{
const ulong val = 20;
ulong x;
ulong y;
for (x = val; ; x += val)
{
for (y = val - 1; y; y--)
{
if (x % y != 0)
{
break;
}
}
if (y == 0)
{
printf("Answer = %u \n", x);
break;
}
}
return 0;
}
第二段代码:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
bool isDivisable(int x);
int main()
{
int a = 20;
while (true)
{
a+=20;
if (isDivisable(a))
{
break;
}
}
printf("%d\n", a);
system("pause");
return 0;
}
bool isDivisable(int x)
{
for (int i = 11; i < 21; i++)
{
if (x%i != 0)return false;
}
return true;
}
此外,这个for循环代表什么?: for(y = val - 1; y; y--) 它会迭代直到达到到底是什么程度?代码(y = val - 1 ;; y--)会产生相同的结果吗?
答案 0 :(得分:1)
您要查找的数字是从1到20的所有数字的 least common multiple (LCM)。在这种情况下,LCM将等于乘以最高的乘积数字素数因子化中每个素数除数的幂。
因此,结果将等于2^4 * 3^2 * 5 * 7 * 11 * 13 * 17 * 19 = 232792560
如果您想查找从1
到N
的所有数字的LCM,您只需使用 sieve of Eratosthenes 查找{{1}中的所有素数} {}} 1
或选择更优化的算法。 C中的示例(重写代码的第一个代码):
N
答案 1 :(得分:0)
这可能是需要考虑的其他因素:
// The least common multiple of numbers from 1 to 20.
// 2^4 * 3^2 * 5 * 7 * 11 * 13 * 17 * 19 = 232792560
// See also https://oeis.org/A003418 for details.
int lcm1_20() {
return 232792560
}
如果您只对相应的值感兴趣(并且您不打算更改参数“20”),那么使用预先计算的值和解释性注释可能就足够了。
在您提供的两个代码中,我会选择第一个代码,主要是因为以下几个方面使第二个版本看起来不太专业:
a+=20
,vs int a = 20;
;还if (x%i != 0)return false;
- 我觉得返回之前的空格看起来更好; isDivisable
包含拼写错误。答案 2 :(得分:-1)
循环'for(y = val - 1; y; y--)'将在y不为0时循环。你的另一个例子永远不会退出。
我更喜欢你提出的第一个算法,因为它消除了不必要的函数调用,并且更易于阅读和理解。