数値の最大素因数を見つけるアルゴリズム


183

数の最大の素因数を計算するための最良のアプローチは何ですか?

私は最も効率的なものは次のようになると思います:

  1. きれいに割れる最小の素数を見つける
  2. 除算の結果が素数かどうかを確認します
  3. そうでない場合は、次に低いものを見つける
  4. 2に進みます。

この仮定は、小さな素因数を計算する方が簡単であることに基づいています。これで大丈夫ですか?他にどのようなアプローチを検討する必要がありますか?

編集:結果が他の2つの素数の積であるときにステップ2が失敗するため、再帰アルゴリズムが必要であるため、2つ以上の素因数が存在する場合、私のアプローチは無駄であることがわかりました。

もう一度編集します。最後に見つかった素数が最も大きい必要があるため、これでも機能することに気づきました。したがって、ステップ2からの素数以外の結果をさらにテストすると、素数が小さくなります。


私のアプローチは次のとおりでした:(1)大きくて可能な数を2で割ります。(2)多数が均等に分割されているかどうかを確認します。(3)その場合、2で割った数が素数かどうかを確認します。ある場合は、それを返します。(4)そうでなければ、ステップ3に戻って2数で割っから1 substract
ケビン・メレディス

1.分割が明確(iは整数(SQR(NUM))に2 =の場合)ことを任意の数を見つける2.何もで発見されなくなるまで、その数で割る(NUM = NUM / I)とRECUR 1の間隔3. NUMが最大の要因である
user3819867

1
小さな素数で除算でき、最後に残るのは最大素因数です(

回答:


134

実際、大きな数の因子を見つけるためのより効率的な方法がいくつかあります(小さなものの場合、試験除算はかなりうまくいきます)。

入力数がその平方根に非常に近い2つの要素を持っている場合に非常に高速な1つの方法は、 フェルマー分解ます。アイデンティティN =(a + b)(a-b)= a ^ 2-b ^ 2を使用し、理解と実装が容易です。残念ながら、それは一般的にあまり速くありません。

100桁までの数を因数分解する最もよく知られた方法は、 二次ふるいです。おまけとして、アルゴリズムの一部は並列​​処理で簡単に実行できます。

私が聞いたさらに別のアルゴリズムは、ポラードのローアルゴリズムですです。一般に、二次ふるいほど効率的ではありませんが、実装が簡単なようです。


数値を2つの因子に分割する方法を決定したら、ここに、数値の最大の素因数を見つけるために考えられる最速のアルゴリズムを示します。

最初に番号自体を格納する優先キューを作成します。反復ごとに、キューから最大数を削除し、それを2つの要素に分割しようとします(もちろん、1をこれらの要素の1つにすることはできません)。このステップが失敗した場合、数は素数であり、あなたの答えがあります!それ以外の場合は、2つの要素をキューに追加して繰り返します。


3
ポラードローと楕円曲線法は、二次ふるいよりも、数値の小さな素因数を取り除くのに優れています。QSは、数に関係なくほぼ同じランタイムを持っています。どちらの方法がより速いかは、数値が何であるかによって異なります。QSは因数分解が困難な数値をより速く分解し、rhoとECMは因数分解が容易な数値をより早く分解します。
tmyklebu

二次変動の提案をありがとうございます。私はクライアントの1つにこれを実装する必要がありました。私が思いついた最初のバージョンは、@ mercutioが彼の質問で提案したものに沿ったものでした。二次解は、クライアントのツールを今math.tools/calculator/prime-factors強化しているものです。
ドース

この問題を効率的に解決する方法がある場合、それはWeb暗号化が安全でないことを意味しませんか?
BKSpurgeon

141

これが私が知っている最高のアルゴリズムです(Pythonで)

def prime_factors(n):
    """Returns all the prime factors of a positive integer"""
    factors = []
    d = 2
    while n > 1:
        while n % d == 0:
            factors.append(d)
            n /= d
        d = d + 1

    return factors


pfs = prime_factors(1000)
largest_prime_factor = max(pfs) # The largest element in the prime factor list

上記の方法O(n)は、最悪の場合(入力が素数の場合)に実行されます。

編集:コメントで示唆されているように、
以下はO(sqrt(n))バージョンです。もう一度コードを示します。

def prime_factors(n):
    """Returns all the prime factors of a positive integer"""
    factors = []
    d = 2
    while n > 1:
        while n % d == 0:
            factors.append(d)
            n /= d
        d = d + 1
        if d*d > n:
            if n > 1: factors.append(n)
            break
    return factors


pfs = prime_factors(1000)
largest_prime_factor = max(pfs) # The largest element in the prime factor list

11
投票する前に、このコードを読んだり実行したりしてください。正常に動作します。コピーして貼り付けてください。書かれているように、prime_factors(1000)は[2,2,2,5,5,5]を返します。これは、2 ^ 3 * 5 ^ 3、別名素因数分解として解釈されます。
トリプティク

11
O(sqrt(n))最悪のケースで実行」-いいえ、最悪のケースで実行さO(n)れます(例:n素数の場合)
シェルドンL.クーパー

16
O(sqrt(n))にするのは簡単で、d * d> nのときにループを停止するだけです。この時点でn> 1の場合、その値を素因数のリストに追加する必要があります。
Sumudu Fernando 2012

5
これに名前はありますか?
Forethinker 2013

11
2は唯一の偶数の素数なので、毎回1を追加する代わりに、d = 2に対して個別に反復してから1ずつインクリメントし、d = 3以降は2ずつインクリメントして、数を減らすことができます。反復回数... :)
tailor_raj 2013年

18

私の答えは、Triptychに基づいていますが、多くの点で改善されています。これは、2と3を超えると、すべての素数が6n-1または6n + 1の形式になるという事実に基づいています。

var largestPrimeFactor;
if(n mod 2 == 0)
{
    largestPrimeFactor = 2;
    n = n / 2 while(n mod 2 == 0);
}
if(n mod 3 == 0)
{
    largestPrimeFactor = 3;
    n = n / 3 while(n mod 3 == 0);
}

multOfSix = 6;
while(multOfSix - 1 <= n)
{
    if(n mod (multOfSix - 1) == 0)
    {
        largestPrimeFactor = multOfSix - 1;
        n = n / largestPrimeFactor while(n mod largestPrimeFactor == 0);
    }

    if(n mod (multOfSix + 1) == 0)
    {
        largestPrimeFactor = multOfSix + 1;
        n = n / largestPrimeFactor while(n mod largestPrimeFactor == 0);
    }
    multOfSix += 6;
}

私は最近、このアルゴリズムがどのように機能するかを説明するブログ記事を書きました。

素数性をテストする必要がない(そしてふるいを作成しない)メソッドは、それらを使用するメソッドよりも高速に実行できると思います。その場合、これはおそらくここで最も速いアルゴリズムです。


12
たとえば、2,3,5を超えると、このアイデアを実際にさらに取ることができます。すべての素数は、30n + k(n> = 0)の形式です。kは、2、3で割り切れない1から29の間の値のみを取ります。または5、つまり7、11、13、17、19、23、29。これまでに見つけた数個の素数ごとに2 * 3 * 5 * 7 * ... * n + kに動的に適応させることもできます。ここで、kはこれらの素数のいずれかで割り切れてはなりません(すべての可能なkが必要ではないことに注意してください)たとえば、210n + kの場合は121を含める必要があります。そうでない場合は331を逃します)
Tobias Kienzler 2013年

2
私はそれがあるべきだと思いますwhile (multOfSix - 1 <= n)
Nader Ghanbari 2014

8

JavaScriptコード:

'option strict';

function largestPrimeFactor(val, divisor = 2) { 
    let square = (val) => Math.pow(val, 2);

    while ((val % divisor) != 0 && square(divisor) <= val) {
        divisor++;
    }

    return square(divisor) <= val
        ? largestPrimeFactor(val / divisor, divisor)
        : val;
}

使用例:

let result = largestPrimeFactor(600851475143);

次にコードの例を示します


7

@Triptychの回答に似ていますが、また異なります。この例では、リストまたは辞書は使用されていません。コードはRubyで書かれている

def largest_prime_factor(number)
  i = 2
  while number > 1
    if number % i == 0
      number /= i;
    else
      i += 1
    end
  end
  return i
end

largest_prime_factor(600851475143)
# => 6857

最後に、読み取り可能で瞬時に(jsで)同時に実行可能なもの。私は無限の素数リストを使おうとしていたのですが、それはすでに100万では遅すぎました。
Ebuall

4

すべての数値は素数の積として表すことができます。例:

102 = 2 x 3 x 17
712 = 2 x 2 x 2 x 89

これらを見つけるには、単に2から始めて、結果が数値の倍数にならないまで単純に除算を続けます。

712 / 2 = 356 .. 356 / 2 = 178 .. 178 / 2 = 89 .. 89 / 89 = 1

この方法を使用する場合、素数を実際に計算する必要はありません。これらはすべて、前のすべての数値で可能な限り数値を因数分解したという事実に基づいて、すべて素数になります。

number = 712;
currNum = number;    // the value we'll actually be working with
for (currFactor in 2 .. number) {
    while (currNum % currFactor == 0) {
        // keep on dividing by this number until we can divide no more!
        currNum = currNum / currFactor     // reduce the currNum
    }
    if (currNum == 1) return currFactor;    // once it hits 1, we're done.
}

はい、しかしこれは恐ろしく非効率的です。すべての2を除算したら、4、6、または...で除算してはいけません。極限をチェックするか、または何らかのtoherアルゴリズムを使用することは、制限において本当にはるかに効率的です。
wnoise 2008年

6
+1は、私が間違っていると思うwnoiseを相殺します。4で除算しようとすると、1回だけ発生し、すぐに失敗します。候補リストから4を削除するよりも悪くないと思います。すべての素数を事前に見つけるよりも確かに高速です。
トリプティク

2
@Beowulf。投票する前にこのコードを実行してみてください。素因数を返します。アルゴリズムを理解していないだけです。
トリプティク

3
コードは問題なく動作しますが、着信数が素数の場合は遅くなります。私はまた、正方形まで実行し、2ずつインクリメントします。ただし、非常に大きな数値の場合は遅すぎる可能性があります。
blabla999 2009年

4
blabla999はまさに正しいです。例は1234567898766700 = 2 * 2 * 5 * 5 * 12345678987667です。に到達するとcurrFactor = 3513642、12345678987667が素数であることがわかり、それを答えとして返す必要があります。代わりに、このコードは12345678987667自体まで列挙を続けます。これは、必要以上に3,513,642倍遅いです。
ネス

4
    //this method skips unnecessary trial divisions and makes 
    //trial division more feasible for finding large primes

    public static void main(String[] args) 
    {
        long n= 1000000000039L; //this is a large prime number 
        long i = 2L;
        int test = 0;

        while (n > 1)
        {
            while (n % i == 0)
            {
                n /= i;     
            }

            i++;

            if(i*i > n && n > 1) 
            {
                System.out.println(n); //prints n if it's prime
                test = 1;
                break;
            }
        }

        if (test == 0)  
            System.out.println(i-1); //prints n if it's the largest prime factor
    }

1
1,000,000,000,039でコードを試しましたか?瞬く間に走るはずです。そうですか?
ネスは

2
試すことなく、事前に知ることができます。10 ^ 12 =(2 * 5)^ 12 = 2 ^ 12 * 5 ^ 12。したがって、whileループはのi値を通過します2,2,2,2,2,2,2,2,2,2,2,2, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5。60回の繰り返しすべて。ただし、(10 ^ 12 + 39)の場合、(10 ^ 12 + 38)回の反復がありi=2,3,4,5,6,...,10^12+39ます。10 ^ 10の操作に1秒かかる場合でも、10 ^ 12には100秒かかります。ただし、実際に必要なのは10 ^ 6回の反復のみであり、10 ^ 10回の演算に1秒かかる場合、10 ^ 6回の実行には1 / 10,000秒かかります。
ネス

1
(10 ^ 12 + 39)が今私がしている素数であることを知らなかったので。私はあなたが言っていることを正確に理解します。
the_prole

1
OK、そうすれば、素数にそれほど大きなスローダウンが発生しないようにコードを変更できます。n= a bおよびa <= bの場合、a a <= b a = n、つまりa a <= n 。そして、a + 1に達した場合、nは確かに素数です。(あなたがこれを組み込むためにあなたの答えを編集したら私にpingしてください)。
Will Ness、

1
何が起こるのlong n = 2*1000000000039Lですか?必要な速度で動作しますか?(また、return;ステートメントを使用してコードを簡略化できますか?)(あなたが私にあなたを黙らせることを止めたいなら、ただそう言ってください;))
ネスは

4

最も簡単な解決策は、相互に再帰的な関数のペアです。

最初の関数はすべての素数を生成します:

  1. 1より大きいすべての自然数のリストから始めます。
  2. 素数でないすべての数値を削除します。つまり、(それ自体以外の)素因数がない数。下記参照。

2番目の関数は、指定された数値の素因数nを昇順で返します。

  1. すべての素数のリストを取る(上記を参照)。
  2. の要素ではないすべての数値を削除しますn

の最大の素因数nは、2番目の関数によって与えられる最後の数です。

このアルゴリズムには、遅延リストまたはcall-by-needセマンティクスを持つ言語(またはデータ構造)が必要です。

明確にするために、Haskellでの上記の1つの(非効率的な)実装を次に示します。

import Control.Monad

-- All the primes
primes = 2 : filter (ap (<=) (head . primeFactors)) [3,5..]

-- Gives the prime factors of its argument
primeFactors = factor primes
  where factor [] n = []
        factor xs@(p:ps) n =
          if p*p > n then [n]
          else let (d,r) = divMod n p in
            if r == 0 then p : factor xs d
            else factor ps n

-- Gives the largest prime factor of its argument
largestFactor = last . primeFactors

これをより速くすることは、どの数が素数であるか、および/またはの因数であるかを検出することについてより賢いことですnが、アルゴリズムは同じままです。


2
n = abs(number);
result = 1;
if (n mod 2 == 0) {
  result = 2;
  while (n mod 2 = 0) n /= 2;
}
for(i=3; i<sqrt(n); i+=2) {
  if (n mod i == 0) {
    result = i;
    while (n mod i = 0)  n /= i;
  }
}
return max(n,result)

因子2と3がすべて削除されている場合、nを6で除算することはできないため、余計なモジュロテストがいくつかあります。ここで他のいくつかの回答に示されているiの素数のみを許可できます。

ここで実際にエラトステネスのふるいを絡み合わせることができます:

  • まず、sqrt(n)までの整数のリストを作成します。
  • forループで、新しいsqrt(n)までのiのすべての倍数を素数でないものとしてマークし、代わりにwhileループを使用します。
  • リストの次の素数にiを設定します。

こちらの質問もご覧ください。


2

これは高速な解決策ではないことを認識しています。遅い解決策を理解しやすいように投稿します。

 public static long largestPrimeFactor(long n) {

        // largest composite factor must be smaller than sqrt
        long sqrt = (long)Math.ceil(Math.sqrt((double)n));

        long largest = -1;

        for(long i = 2; i <= sqrt; i++) {
            if(n % i == 0) {
                long test = largestPrimeFactor(n/i);
                if(test > largest) {
                    largest = test;
                }
            }
        }

        if(largest != -1) {
            return largest;
        }

        // number is prime
        return n;
    } 

1

数からすべての素因数を取り除くことによるPython反復アプローチ

def primef(n):
    if n <= 3:
        return n
    if n % 2 == 0:
        return primef(n/2)
    elif n % 3 ==0:
        return primef(n/3)
    else:
        for i in range(5, int((n)**0.5) + 1, 6):
            #print i
            if n % i == 0:
                return primef(n/i)
            if n % (i + 2) == 0:
                return primef(n/(i+2))
    return n

1

私は現在の素因数で数を割り続けるアルゴリズムを使用しています。

私のpython 3の解決策:

def PrimeFactor(n):
    m = n
    while n%2==0:
        n = n//2
    if n == 1:         # check if only 2 is largest Prime Factor 
        return 2
    i = 3
    sqrt = int(m**(0.5))  # loop till square root of number
    last = 0              # to store last prime Factor i.e. Largest Prime Factor
    while i <= sqrt :
        while n%i == 0:
            n = n//i       # reduce the number by dividing it by it's Prime Factor
            last = i
        i+=2
    if n> last:            # the remaining number(n) is also Factor of number 
        return n
    else:
        return last
print(PrimeFactor(int(input()))) 

入力:10 出力:5

入力:600851475143 出力:6857


0

これがc#での私の試みです。最後の出力は、数値の最大の素因数です。チェックしてみました。

namespace Problem_Prime
{
  class Program
  {
    static void Main(string[] args)
    {
      /*
       The prime factors of 13195 are 5, 7, 13 and 29.

      What is the largest prime factor of the number 600851475143 ?
       */
      long x = 600851475143;
      long y = 2;
      while (y < x)
      {
        if (x % y == 0)
        {
          // y is a factor of x, but is it prime
          if (IsPrime(y))
          {
            Console.WriteLine(y);
          }
          x /= y;
        }

        y++;

      }
      Console.WriteLine(y);
      Console.ReadLine();
    }
    static bool IsPrime(long number)
    {
      //check for evenness
      if (number % 2 == 0)
      {
        if (number == 2)
        {
          return true;
        }
        return false;
      }
      //don't need to check past the square root
      long max = (long)Math.Sqrt(number);
      for (int i = 3; i <= max; i += 2)
      {
        if ((number % i) == 0)
        {
          return false;
        }
      }
      return true;
    }

  }
}

0
#python implementation
import math
n = 600851475143
i = 2
factors=set([])
while i<math.sqrt(n):
   while n%i==0:
       n=n/i
       factors.add(i)
   i+=1
factors.add(n)
largest=max(factors)
print factors
print largest

1
25は25の最大の素因数ですか?
ネスは2014年

0

C ++の再帰を使用して、数値の最大素因数を計算します。コードの動作を以下に説明します。

int getLargestPrime(int number) {
    int factor = number; // assumes that the largest prime factor is the number itself
    for (int i = 2; (i*i) <= number; i++) { // iterates to the square root of the number till it finds the first(smallest) factor
        if (number % i == 0) { // checks if the current number(i) is a factor
            factor = max(i, number / i); // stores the larger number among the factors
            break; // breaks the loop on when a factor is found
        }
    }
    if (factor == number) // base case of recursion
        return number;
    return getLargestPrime(factor); // recursively calls itself
}

0

これが最大の素因数をすばやく計算するための私のアプローチです。これは、modifiedにx非素因数が含まれていないという事実に基づいています。それを達成するために、x因子が見つかるとすぐに分割します。次に、残っている唯一のことは、最大の因子を返すことです。それはすでにプライムです。

コード(Haskell):

f max' x i | i > x = max'
           | x `rem` i == 0 = f i (x `div` i) i  -- Divide x by its factor
           | otherwise = f max' x (i + 1)  -- Check for the next possible factor

g x = f 2 x 2

しかし、これもすべての偶数で除算しようとしないのですか?
Janus Troelsen、2016

0

次のC ++アルゴリズムは最適ではありませんが、10億未満の数で機能し、かなり高速です

#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;
 }

0

このソリューションは「ジェームズワン」によってウェブ上で見つかりました

public static int getLargestPrime( int number) {

    if (number <= 1) return -1;

    for (int i = number - 1; i > 1; i--) {
        if (number % i == 0) {
            number = i;
        }
    }
    return number;
}

0

ふるいを使用した素因数:

#include <bits/stdc++.h>
using namespace std;
#define N 10001  
typedef long long ll;
bool visit[N];
vector<int> prime;

void sieve()
{
            memset( visit , 0 , sizeof(visit));
            for( int i=2;i<N;i++ )
            {
                if( visit[i] == 0)
                {
                    prime.push_back(i);
                    for( int j=i*2; j<N; j=j+i )
                    {
                        visit[j] = 1;
                    }
                }
            }   
}
void sol(long long n, vector<int>&prime)
{
            ll ans = n;
            for(int i=0; i<prime.size() || prime[i]>n; i++)
            {
                while(n%prime[i]==0)
                {
                    n=n/prime[i];
                    ans = prime[i];
                }
            }
            ans = max(ans, n);
            cout<<ans<<endl;
}
int main() 
{
           ll tc, n;
           sieve();

           cin>>n;
           sol(n, prime);

           return 0;
}

-1

与えられたアルゴリズムのステップ#2は、それほど効率的なアプローチではないように思えます。あなたはそれが素数であるという合理的な期待はありません。

また、エラトステネスのふるいを示唆する以前の答えは完全に間違っています。123456789を因数分解する2つのプログラムを作成しました。1つはSieveに基づいており、1つは以下に基づいています。

1)  Test = 2 
2)  Current = Number to test 
3)  If Current Mod Test = 0 then  
3a)     Current = Current Div Test 
3b)     Largest = Test
3c)     Goto 3. 
4)  Inc(Test) 
5)  If Current < Test goto 4
6)  Return Largest

このバージョンはSieveより90倍高速でした。

問題は、最近のプロセッサーでは、操作のタイプが操作の数よりもはるかに少ないことです。言うまでもなく、上記のアルゴリズムはキャッシュで実行できますが、Sieveはできません。ふるいは、すべての合成数を打ち消す多くの演算を使用します。

また、特定された要因を分割することで、テストする必要のあるスペースが減少することにも注意してください。


それが私が言ったことですが、投票されました:(問題は、数値に非常に大きな素因数(それ自体など)がある場合、このメソッドはその数値までループする必要があるということです。多くの場合ただし、この方法は非常に効率的です
nickf 2008年

あなたのことを読み返すのも同じですが、あなたの最初の部分は混乱しています。
Loren Pechtel、2008年

これを試してみてください143816789988504044536402352738195137863656439、これがどれだけ効率的かを教えてください...
MichaelICE

-1

最初に素数を格納するリストを計算します。例:2 3 5 7 11 13 ...

数値を素因数分解するたびに、Triptychによる実装を使用しますが、自然整数ではなく、この素数のリストを繰り返します。


-1

Javaの場合:

以下のためのint値:

public static int[] primeFactors(int value) {
    int[] a = new int[31];
    int i = 0, j;
    int num = value;
    while (num % 2 == 0) {
        a[i++] = 2;
        num /= 2;
    }
    j = 3;
    while (j <= Math.sqrt(num) + 1) {
        if (num % j == 0) {
            a[i++] = j;
            num /= j;
        } else {
            j += 2;
        }
    }
    if (num > 1) {
        a[i++] = num;
    }
    int[] b = Arrays.copyOf(a, i);
    return b;
}

以下のためのlong値:

static long[] getFactors(long value) {
    long[] a = new long[63];
    int i = 0;
    long num = value;
    while (num % 2 == 0) {
        a[i++] = 2;
        num /= 2;
    }
    long j = 3;
    while (j <= Math.sqrt(num) + 1) {
        if (num % j == 0) {
            a[i++] = j;
            num /= j;
        } else {
            j += 2;
        }
    }
    if (num > 1) {
        a[i++] = num;
    }
    long[] b = Arrays.copyOf(a, i);
    return b;
}

-2

これはおそらく常に速いとは限りませんが、大きな素数を見つけることについてはより楽観的です:

  1. N あなたの番号です
  2. それが素数なら return(N)
  3. までの素数を計算する Sqrt(N)
  4. プライムを降順で調べます(最初に大きい順)
    • もしN is divisible by Primeその後、Return(Prime)

編集:ステップ3では、エラトステネスのふるいやアトキンスのふるいなど、好きなものを使用できますが、ふるいだけでは最大の素因を見つけることはできません。(それがSQLMenaceの投稿を公式の回答として選択しない理由です...)


1
それが素数かどうかを判断するために試行因数分解を行う必要はありませんか(ステップ2)?また、最大の素因数15を見つけることを検討してください。sqrt(15)までの素数は2と3です。しかし、最大の素因数は5です。そうではありませんか?同様に20と
ジョナサン・レフラー

-3

nよりも小さいすべての可能な素数をどこかに格納し、それらを反復して最大の除数を見つけるのは良いことだと思います。あなたはprime-numbers.orgから素数を得ることができます

もちろん、私はあなたの数はあまり大きくないと思います:)


-3

最速ではありませんが、うまくいきます!

    static bool IsPrime(long num)
    {
        long checkUpTo = (long)Math.Ceiling(Math.Sqrt(num));
        for (long i = 2; i <= checkUpTo; i++)
        {
            if (num % i == 0)
                return false;
        }
        return true;
    }

これは質問に対する答えではありません。;-)問題は、素数性をチェックするのではなく、最大の素因数を見つけることに関するものでした。
Hans-PeterStörr、2009年

(long i = 3; i <checkUpTo; i + = 2)としてループを初期化する方がはるかに効率的です
cjk

-3

これはジェネレーターとして提供されている同じfunction @ Triptychですが、これも少し簡略化されています。

def primes(n):
    d = 2
    while (n > 1):
        while (n%d==0):
            yield d
            n /= d
        d += 1

最大素数は、次のようにして見つけることができます。

n= 373764623
max(primes(n))

そして、使用して見つかった要因のリスト:

list(primes(n))

-6
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include <time.h>

factor(long int n)
{
long int i,j;
while(n>=4)
 {
if(n%2==0) {  n=n/2;   i=2;   }

 else
 { i=3;
j=0;
  while(j==0)
  {
   if(n%i==0)
   {j=1;
   n=n/i;
   }
   i=i+2;
  }
 i-=2;
 }
 }
return i;
 }

 void main()
 { 
  clock_t start = clock();
  long int n,sp;
  clrscr();
  printf("enter value of n");
  scanf("%ld",&n);
  sp=factor(n);
  printf("largest prime factor is %ld",sp);

  printf("Time elapsed: %f\n", ((double)clock() - start) / CLOCKS_PER_SEC);
  getch();
 }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.