3

我编写此代码是为了找到给定数字的除数。我尝试实现的方法找到所有素数因子(有效)并取相似素数的数量加一(给出除数的数量)。

例如 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;

我只是无法弄清楚我错过了什么。

4

3 回答 3

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;
}
于 2012-12-23T01:38:19.557 回答
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您从未包含的内容。

于 2012-12-23T01:36:56.623 回答
1

你的代码有很多问题(而且goto中断循环很丑陋),但你的代码的一个主要问题是,在你进入for循环之后,你设置next的值与i.

然后,您测试一些东西(即 ifi均分num,但这没关系)(这是关键部分,您测试 if iis equal to next,您只需将它们设置为相等。

因此,您的代码永远没有机会输入else相应的部分if,即您将除数乘以exponent + 1.

结果,您的代码总是打印1,这不是您想要的。

-O1PS:作为死代码消除的一部分,编译器可能会完全优化其他内容,如果我启用优化或更高版本,这就是我的 gcc 4.7 实际上所做的。

于 2012-12-23T02:04:15.953 回答