寻找主要因素

时间:2012-08-12 17:28:04

标签: c++ primes prime-factoring factorization

#include <iostream>
using namespace std;

void whosprime(long long x)
{
    bool imPrime = true;

    for(int i = 1; i <= x; i++)
    {
        for(int z = 2; z <= x; z++)
        {
            if((i != z) && (i%z == 0))
            {
                imPrime = false;
                break;
            }
        }

        if(imPrime && x%i == 0)
            cout << i << endl;

        imPrime = true;
    }    
}

int main()
{
    long long r = 600851475143LL;
    whosprime(r);  
}

我试图找到项目Euler上由Problem 3指定的数字600851475143的素因子(它要求最高的素数因子,但我想找到所有这些因素)。但是,当我尝试运行此程序时,我没有得到任何结果。是否与我的程序占用这么大的数字有多长,甚至与数字本身有关?

此外,有哪些更有效的方法可以解决这个问题,你有什么建议可以解决这些更优雅的解决方案,因为我正在解决这个问题吗?

一如既往,谢谢!

12 个答案:

答案 0 :(得分:26)

你的算法错了;你不需要。这是试验部门对整数因子分解的伪代码:

define factors(n)

    z = 2

    while (z * z <= n)

        if (n % z == 0)
            output z
            n /= z

        else
            z++

    if n > 1
        output n

我将留给您使用适当的整数数据类型转换为C ++。

编辑:修正了比较(谢谢,哈罗德)并为Bob John添加了讨论:

了解这一点的最简单方法是举个例子。考虑n = 13195的因子分解。最初z = 2,但是将13195除以2会得到1的余数,所以else子句设置z = 3并且我们循环。现在n不能被3或4整除,但是当z = 5时,将13195除以5时的余数为零,因此输出5并将13195除以5使得n = 2639并且z = 5不变。现在新的n = 2639不能被5或6整除,但是可以被7整除,所以输出7并设置n = 2639/7 = 377.现在我们继续z = 7,剩下的就像是除法一样通过8,9和10,11和12,但377/13 = 29没有余数,所以输出13并设置n = 29.此时z = 13,z * z = 169,这是大于29,所以29是素数,是13195的最终因子,因此输出29.完全因子分解为5 * 7 * 13 * 29 = 13195。

有更好的算法可以使用试验除法对整数进行因式分解,甚至更强大的算法可以使用除了试验除法之外的技术对整数进行因式分解,但上面显示的算法可以帮助您入门,并且足以用于Project Euler#3。当您准备好了更多内容时,请查看here

答案 1 :(得分:3)

600851475143超出了int的范围

void whosprime(int x) //<-----fix heere ok?
{
    bool imPrime = true;

    for(int i = 1; i <= x; i++)
    {... 
      ...

答案 2 :(得分:2)

使用@ user448810的伪代码的C ++实现:

#include <iostream>
using namespace std;

void factors(long long n) {
    long long z = 2;
    while (z * z <= n) {
        if (n % z == 0) {
            cout << z << endl;
            n /= z;
        } else {
            z++;
        }
    }
    if (n > 1) {
        cout << n << endl;
    }
}

int main(int argc, char *argv[]) {
    long long r = atoll(argv[1]);
    factors(r);
}

// g++ factors.cpp -o factors ; factors 600851475143

使用相同算法的Perl实现如下 运行速度慢10-15倍(对于n = 600851475143,Perl 0.01秒)

#!/usr/bin/perl
use warnings;
use strict;

sub factors {
    my $n = shift;
    my $z = 2;
    while ($z * $z <= $n) {
        if ( $n % $z ) {
            $z++;
        } else {
            print "$z\n";
            $n /= $z;
        }
    }
    if ( $n > 1 ) {
        print "$n\n"
    }
}

factors(shift);

# factors 600851475143

答案 3 :(得分:1)

# include <stdio.h>
# include <math.h>
void primeFactors(int n)
{
    while (n%2 == 0)
    {
        printf("%d ", 2);
        n = n/2;
    }
    for (int i = 3; i <= sqrt(n); i = i+2)
    {
        while (n%i == 0)
        {
            printf("%d ", i);
            n = n/i;
        }
    }
   if (n > 2)
        printf ("%d ", n);
}
int main()
{
    int n = 315;
    primeFactors(n);
    return 0;
}

答案 4 :(得分:0)

编辑:我错了(见评论)。我会删除,但我错误的方式有助于表明程序中特别需要这么长时间来产生输出,所以我会留下它: - )

这个程序应该立即打印1(我不打算讨论是否是最优质的,这正是你的程序所做的)。因此,如果你什么也看不见,那么问题不在于执行速度,那么你运行程序的方式就会出现问题。

答案 5 :(得分:0)

尝试以下代码:

counter = sqrt(n)
i = 2;

while (i <= counter)
    if (n % i == 0)
        output i
    else
        i++

答案 6 :(得分:0)

这是我的代码,可以很好地找到任何数字的最大素数因子:

#include <iostream>
using namespace std;

// --> is_prime <--
// Determines if the integer accepted is prime or not
bool is_prime(int n){
    int i,count=0;
    if(n==1 || n==2)
      return true;
    if(n%2==0)
      return false;
    for(i=1;i<=n;i++){
    if(n%i==0)
        count++;
    }
    if(count==2)
      return true;
    else
      return false;
 }
 // --> nextPrime <--
 // Finds and returns the next prime number
 int nextPrime(int prime){
     bool a = false;
     while (a == false){
         prime++;
         if (is_prime(prime))
            a = true;
     }
  return prime;
 }
 // ----- M A I N ------
 int main(){

      int value = 13195;
      int prime = 2;
      bool done = false;

      while (done == false){
          if (value%prime == 0){
             value = value/prime;
             if (is_prime(value)){
                 done = true;
             }
          } else {
             prime = nextPrime(prime);
          }
      }
        cout << "Largest prime factor: " << value << endl;
 }

请记住,如果你想找到极大数量的最大素因子,你必须使用“长”字样。变量类型而不是&#39; int&#39;并调整算法以加快处理速度。

答案 7 :(得分:0)

短而明确的气息:

    int main()
    {
        int MAX = 13195;

        for (int i = 2; i <= MAX; i++)
        {
             while (MAX % i == 0)
             {
                  MAX /= i;
                  cout <<  i << ", " << flush;   // display only prime factors
             }
        return 0;
    }

答案 8 :(得分:0)

这是您问题中最简单易懂的解决方案之一。 它可能不像上面提供的其他解决方案那样高效,但对于像我这样的初学者来说是肯定的。

int main() {

int num = 0;
cout <<"Enter number\n";
cin >> num;
int fac = 2;  
while (num > 1) {
    if (num % fac == 0) {
        cout << fac<<endl;
        num=num / fac;
    }
    else fac++;
}
return 0;

}

答案 9 :(得分:0)

简单方法:

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;

ll largeFactor(ll n)
{
        ll ma=0;
        for(ll i=2; i*i<=n; i++)
        {
            while(n%i == 0)
            {
                n=n/i;
                ma=i;
            }
        }
        ma = max(ma, n);
        return ma;
}

int main() 
{
    ll n;
    cin>>n;
    cout<<largeFactor(n)<<endl;
    return 0;
}

使用主筛ideone实施。

答案 10 :(得分:0)

由于600851475143超出了int的范围,因此无法在此处使用单个long类型,因此在这里要解决的问题是,我们必须在typedef的帮助下定义自己的类型。 现在ll的范围大约是9,223,372,036,854,775,807。

typedef long long int LL

答案 11 :(得分:-2)

试试这段代码。绝对是最好和最有效的:

long long number;
bool isRepetitive;

for (int i = 2; i <= number; i++) {
    isRepetitive = false;
    while (number % i == 0) {
        if(!isRepetitive){
            cout << i << endl;
            isRepetitive = true;
        }
        number /= i;
    }
}

享受! ☻