Euler Totient:优化

时间:2013-11-01 12:36:01

标签: c optimization

int main(void)
{
  int n, div, a, b;
  double phi;
  printf("Enter n:\n");
  if (scanf("%d", &n) < 1 || n <= 0)
  {
    printf("Wrong input.\n");
    return 1;
  }

  a = n;
  div = 2;
  phi = n;

  while (n != 1)
  {
    if (n % div != 0)
      div++;
    else
    {
      n = n / div;
      if (b != div)
      {
        b = div;
        phi = phi * (1.0 - 1.0 / div);
      }
    }
  }

  printf("phi(%d) = %.f\n", a, phi);

  return 0;
}

这是我作为学校作业制作的Euler's Totient的代码。该程序似乎运行良好,但仍然很慢。我怎样才能让它更快?

2 个答案:

答案 0 :(得分:1)

首先检查div=2

之后你只需要检查奇数,所以你可以使用div += 2。这应该把时间缩短一半。

答案 1 :(得分:0)

我不确定是否有更好的算法,但我们可以从低悬的果实开始:你正在测试所有数字n以找到它的除数。这是多余的,因为从φ(n)的定义我们知道我们只需要它的素因子。

很好,有人可能会说,我们只是将线性搜索变成了超多项式问题。

不一定。

选择P6主要候选人生成器:

def P6():
    yield 2
    yield 3
    i = 5
    while True:
        yield i
        if i % 6 == 1:
            i += 2
        i += 2

让我们在其上构建一个分解函数:

def factors(n):
    d = {}
    primes = p6()
    for p in primes:
        while n % p == 0:
            n /= p
            d[p] = d.setdefault(p, 0) + 1
        if n == 1:
            return d

现在找到φ(n)是微不足道的。尝试在C中实现它并测量差异。如果您需要它更快,像GMP这样的库可以提供更快的分解程序。