【问题标题】:Find a better algorithm for prime factors of a number [closed]为数字的素数找到更好的算法[关闭]
【发布时间】:2016-08-25 19:38:54
【问题描述】:

我被分配了一个程序,该程序采用正整数并显示其主要因素。

我观察到,当给出大于 500000 的数字时,我的程序需要很长时间才能找到素因数。

最后,我失败了,因为当给定整数 776621 时,程序花了超过 10 秒来计算结果。 我想了解如何优化我的代码,以便更快地给出结果。 这是我的代码:

#include <stdio.h>
#include <stdlib.h>

int ft_isprime(int num)
{
    int i;
    int j;

    i = 0;
    j = 2;
    if (num <= 1 && num >= 0)
        return (0);
    if (num >= 2 && num <= 3)
        return (1);
    while (j < num)
    {
        if (num % j == 0)
            return (0);
        j++;
    }
    return (1);
}
int main(int argc, char **argv)
{
    int num;
    int divisor;
    int prime_divisors[30];
    int i;

    i = 0;
    num = 0;
    if (argc == 2)
        num = atoi(argv[1]);
    divisor = num;
    if (argc != 2)
    {
        printf("\n");
        return (0);
    }
    if (num == 1)
    {
        printf("1\n");
        return (0);
    }
    if (ft_isprime(num))
    {
        printf("%d\n", num);
        return (0);
    }
    while (num > 0 && divisor > 0)
    {
        if (ft_isprime(divisor))
        {
            if (num % divisor == 0)
            {
                num = num / divisor;
                prime_divisors[i] = divisor;
                i++;
                continue;
            }
        }
        divisor--;
    }
    while (i > 0)
    {
        if (i == 1)
            printf("%d", prime_divisors[i-1]);
        else
            printf("%d*", prime_divisors[i-1]);
        i--;
    }
    printf("\n");
    return (0);
}

输出示例:

$> ./fprime 225225 | cat -e
3*3*5*5*7*11*13$
$> ./fprime 8333325 | cat -e
3*3*5*5*7*11*13*37$
$> ./fprime 9539 | cat -e
9539$
$> ./fprime 804577 | cat -e
804577$
$> ./fprime 42 | cat -e
2*3*7$
$> ./fprime 1 | cat -e
1$
$> ./fprime | cat -e
$
$> ./fprime 42 21 | cat -e
$

【问题讨论】:

  • 您知道质数分解问题被认为是困难吗?而整个现代密码学都依赖于这个假设?
  • 我投票结束这个问题,因为它是关于优化工作代码的,更适合codereview.stackexchange.com
  • 其实不是优化代码的问题;编译器会为你处理这些。你需要优化的是你的想法;思考如何设计更好的算法。你应该避免做不必要的计算(很明显,我知道)。例如,您检查每个试除数的素数,但有必要吗?假设您从 2 开始,然后继续使用更大的数字。一旦你删除了所有的 2,任何偶数都可以除掉剩下的吗?一旦你删除了所有的 3,任何 3 的倍数都会成为一个因素吗?那么你真的关心试除数是否是素数吗?
  • 另外,如果您从 2 开始依次尝试潜在除数,则可以在到达 ceil(sqrt(num)) 时停止检查。

标签: c algorithm gcc primes prime-factoring


【解决方案1】:

这是一个运行速度更快的实现:

#include <vector>

using namespace std;

bool isPrime(int n) {
  if (n == 1) {
    return false;
  }

  for (int i = 2; i <= sqrt(n); i++) {
    if (n % i == 0) {
      return false;
    }
  }

  return true;
}

vector<int> getPrimeFactors(int n) {
  if (n == 1) {
    return vector<int>();
  } else if (isPrime(n)) {
    return vector<int>(1, n);
  }

  vector<int> primeFactors;
  while(n > 1) {
    // find next factor
    int factor = 2;
    for (factor = 2; factor <= sqrt(n); factor++) {
      if (n % factor == 0) {
        break;
      }
    }

    // remove as many factors as possible
    while (n % factor == 0 && n > 1) {
      n /= factor;
      primeFactors.push_back(factor);
    }

    if (isPrime(n)) {
      primeFactors.push_back(n);
      n = 0;
    }
  }

  return primeFactors;
}

【讨论】:

  • 谢谢,在传递整数 1492002 时,使用 sqrt 的想法将运行时间提高了 2400%。
猜你喜欢
  • 2017-11-27
  • 1970-01-01
  • 2011-12-17
  • 1970-01-01
  • 1970-01-01
  • 2016-05-31
  • 2013-03-28
  • 1970-01-01
  • 2020-02-14
相关资源
最近更新 更多