这是一个计算一个数字的除数的数量的程序,但是它给出的除数比该数字的除数少一个。
#include <stdio.h>
int i = 20;
int divisor;
int total;
int main()
{
for (divisor = 1; divisor <= i; divisor++)
{
if ((i % divisor == 0) && (i != divisor))
{
total = total++;
}
}
printf("%d %d\n", i, total);
return 0;
}
数字20有6个除数,但程序说有5个除数。
答案 0 :(得分:5)
&& (i != divisor)
表示20
不会被视为除数。如果你想要它被考虑,抛弃那些代码,你将获得整套,{1, 2, 4, 5, 10, 20}
。
即使您没有希望将该数字视为除数,您仍然可以放弃该代码,只需使用<
代替<=
{{1}声明。
和
for
完全没必要。它甚至可能是未定义的,我现在只是懒得检查它并不重要,因为没有人长时间写这样的代码: - )
使用:
total = total++;
或(更好):
total = total + 1;
答案 1 :(得分:1)
除数计数可能比其中任何一种都更简单,也更快。需要注意的关键事实是,如果p是n的除数,那么n / p也是如此。每当p不是n的平方根时,你就会得到每格分数的两个除数,而不是一个。
int divcount(int n)
{
int i, j, count=0;
for (i=1, j=n; i<j; j = n/++i)
{
if (i*j == n)
count += 2;
}
if (i == j && i*j == n)
++count;
return count;
}
使用sqrt(n)除法和sqrt(n)乘法完成工作。我选择那个因为,虽然j = n / i和另一个j%i可以在大多数CPU上使用单个除法指令完成,但我还没有看到编译器接受该优化。由于乘法是现代桌面处理器上的单时钟,因此i * j == n测试比第二个分区便宜得多。
PS:如果你需要一个除数列表,它们会作为i和j值出现在循环中,如果n是一个正方形,可能最后是i == j == sqrt(n)值。
答案 2 :(得分:0)
您已按照给定答案中的说明添加了额外的支票&& (i != divisor)
。
在这里,我使用素数因子分解编写了相同的程序。这是查找大数(reference)的除数的快速方法。
// this function return the number of divisor for n.
// if n = (m^a) (n^b) ... where m, n.. are prime factors of n
// then number of divisor d(n) = (a+1)*(b+1)..
int divisorcount(int n){
int divider = 2;
int limit = n/2;
int divisorCount = 1;
int power = 0;
// loop through i=2...n/2
while(divider<=limit){
if(n%divider==0){
// dividing numper using prime factor
// (as smallest number devide a number
// is it's prime factor) and increase the
// power term for prime factor.
power++;
n/=divider;
}
else{
if(power != 0){
// use the prime factor count to calculate
// divisor count.
divisorCount*=(power+1);
}
power = 0;
divider++;
// if n become 1 then we have completed the
// prime factorization of n.
if(n==1){
break;
}
}
}
return divisorCount;
}