我编写此代码是为了找到给定数字的除数的数量。我试图实现的方法找到了所有的素数因子(有效)并且取了一些相似的素数加一(给出了除数的数量)。
e.g。 28 = 2 * 2 * 7 - > (2 + 1)*(1 + 1)= 6
这是我的尝试:
int num = 20;
int next = 0;
int exponent = 0;
int numberOfDivisors = 1;
start:
for (int i = 2; i <= num; i++)
{
next = i;
if (num%i == 0)
{
if (i == next)
{
exponent++;
}
else
{
numberOfDivisors *= (exponent+1);
exponent = 0;
}
if (num != i)
{
num /= i;
goto start;
}
}
}
std::cout << numberOfDivisors << std::endl;
我无法弄清楚我错过了什么。
答案 0 :(得分:6)
从评论中可以看出,使用goto很糟糕。经过一些清理后,您的代码将归结为:
#include <iostream>
int main() {
int num = 20;
int numberOfDivisors = 1;
for (int i = 2; i <= num; i++)
{
int exponent = 0;
while (num % i == 0) {
exponent++;
num /= i;
}
numberOfDivisors *= (exponent+1);
}
std::cout << numberOfDivisors << std::endl;
return 0;
}
答案 1 :(得分:1)
实际上,goto
没有帮助,因为您已经检查了较低的素因子,因此无需将i
放回2
。
int numberOfDivisors = 1;
int exponent = 1;
int i = 2;
while (i <= num) {
if (num%i == 0) {
exponent++;
num /= i;
}
else {
numberOfDivisors *= exponent;
exponent = 1;
i++;
}
}
numberOfDivisors *= exponent; // <-- you were missing this, mainly
您的代码与样式或性能无关的实际问题是您的循环完成了一些您从未包含的exponent
。
答案 2 :(得分:1)
您的代码存在许多问题(并且goto
中断循环只是丑陋),但代码的一个主要问题是,在您输入for
循环后,您设置{ {1}}具有与next
相同的值。
然后,你测试一些东西(即,如果i
均匀地划分i
,但这没关系)和(这里是关键部分,你测试是否num
等于i
,您只是将它们设置为相等。
因此,您的代码永远不会有机会输入相应next
的{{1}}部分,您可以将除数的数量乘以else
。
因此,您的代码始终打印if
,这不是您想要的。
P.S。:作为消除死代码的一部分,编译器可以完全优化其他内容,如果我启用优化exponent + 1
或更高版本,这就是我的gcc 4.7实际执行的操作。