与えられた数の約数を計算するアルゴリズム


177

与えられた数の約数を計算するのに最も最適なアルゴリズムは何ですか(パフォーマンスの観点から)?

疑似コードやいくつかの例へのリンクを提供できればすばらしいでしょう。

編集:すべての回答は非常に役に立ちました、ありがとうございます。私はアトキンのふるいを実装し、その後、ジョナサンレフラーが示したものと同様のものを使用します。Justin Bozonierによって投稿されたリンクには、私が欲しかったものに関する詳細情報があります。


いくつかの要因を考え出すあなたの要求を考えると、あいまいです。一意でない素数の数を探していると思いますが、これを望まない場合は、因数が1の場合は常に1を返し、それ以外の場合は2を返すようにプログラムを記述してください。0は変更が必要になる可能性があります...
ジャスティンボゾニエ2008

@sker:除数が必要な値の範囲はありますか?係数を計算するには多くの方法があり、それぞれの方法は特定の範囲により適しています。
アンデターナー

2
ここでは、関連する興味深い問題であるprojecteuler.net/problem=12
daniloquio

1
編集されたWikipediaの記事からのナイーブSieve of Atkinは、最大のホイール分解されたエラトステネスのSieve of Eratosthenesよりも速くなることはなく、ページセグメントバージョンはSoEをさらに支持しています(SoEプライムシーブとSoAプライムゲンを参照)。 AtkinのパートナーBernsteinによって実装されました。彼らの研究がSoAをより速く証明したことはよくある誤ったインターネット知識ですが、彼らはこれを証明するために使用されたSoEの最適化を人為的に制限しました。詳細については私のSoA回答を参照しください
GordonBGood

回答:


78

Dmitriyは、AtkinのSieveが素数リストを生成することを望んでいますが、それが問題全体を処理するとは思いません。これで素数のリストが作成されたので、それらの素数のうちいくつが除数として機能するか(およびその頻度)を確認する必要があります。

これはアルゴ用のpythonです。 ここて「Subject:math-need divisors algorithm」を検索してください。ただし、返すのではなく、リスト内の項目の数を数えるだけです。

これが数学的に何をする必要があるかを正確に説明するDr. Mathです。

基本的に、それはあなたの数nが:(
n = a^x * b^y * c^z
ここで、a、b、およびcはnの素数であり、x、y、およびzはその約数が繰り返される回数です)である場合、すべての約数の合計数は次のようになります。
(x + 1) * (y + 1) * (z + 1)

編集:ところで、私がこれを正しく理解している場合、a、b、cなどを見つけるには、貪欲なアルゴに相当することを実行する必要があります。最大の素数から始めて、それ以上掛けてnを超えるまでそれを掛けます。次に、次に低い因子に移動し、前の素数に現在の素数を掛けた回数を掛け、次がnを超えるまで素数を掛け続けます...など。掛けた回数を追跡します一緒に約数を取り、それらの数値を上記の数式に適用します。

私のアルゴの説明について100%確信はありませんが、それがそうでなければ、それは似たようなものです。


1
あなたが大きな数を因数分解しているなら、あなたは素数リストを見る必要さえありません。可能性の全範囲をできるだけ早く排除したい!詳細については私の答えを参照してください。
user11318 '09 / 09/21

私はこれが2年前だったことに気づきましたが、あなたのpythonアルゴリンクが壊れています。
jb。

2
だから、n = (a^x * b^y * c^z)-(x + 1) * (y + 1) * (z + 1)ルールがある
SIslam

1
@Shashankが言うように、「編集:」セクションのアルゴリズムは間違っています:n = 45 = 3 * 3 * 5と仮定します。最大の素数は5ですが、nを超えるまでこれを乗算すると、アルゴリズムは因子5の2つのコピーがあることを報告します(5 * 5 = 25 <45であるため)。
j_random_hacker

1
「アトキンのふるい」の実行時の複雑さは、せいぜいO(N / log(log(N)))です。1 ... Sqrt(n)のすべての可能な除数を総当たりチェックすると、ランタイムの複雑度がO(Sqrt(N))になり、はるかに優れています。なぜこの答えが受け入れられたのですか?
le_m 2017年

47

アトキンのふるいよりも因数分解のテクニックはたくさんあります。たとえば、5893を因数分解したいとします。そのsqrtは76.76です...次に、5933を二乗の積として書こうとします。よく(77 * 77-5893)= 36は6の2乗なので、5893 = 77 * 77-6 * 6 =(77 + 6)(77-6)= 83 * 71です。それがうまくいかなかった場合、78 * 78-5893が完全な正方形であるかどうかを確認しました。等々。この手法を使用すると、個々の素数をテストするよりもはるかに速く、nの平方根に近い因子をすばやくテストできます。大きな素数を除外するこの手法をふるいと組み合わせると、ふるいだけの場合よりもはるかに優れた因数分解法が得られます。

そして、これは開発された数多くのテクニックの1つにすぎません。これはかなり単純なものです。たとえば、楕円曲線に基づく因数分解手法を理解するのに十分な数の理論を学ぶには、長い時間がかかります。(私はそれらが存在することを知っています。私はそれらを理解していません。)

したがって、小さな整数を扱っていない限り、私はその問題を自分で解決しようとはしません。代わりに、非常に効率的なソリューションが既に実装されているPARIライブラリのようなものを使用する方法を見つけようと思います。これで、約.05秒で124321342332143213122323434312213424231341のようなランダムな40桁の数値を因数分解できます。(ご参考までに、その因数分解は29 * 439 * 1321 * 157907 * 284749 * 33843676813 * 4857795469949です。アトキンのふるいを使用してこれを理解できなかったと確信しています...)


1
あなたのテクニックはとても賢いですが、それは数がいくつ要素を持つか教えてくれませんか?
sker

23
素因数分解を行ったら、いくつの因子があるかを理解するのは簡単です。素因数がp1、p2、...、pkであり、m1、m2、...、mk回繰り返されるとします。次に、(1 + m1)(1 + m2)...(1 + mk)係数があります。
user11318 '09 / 09/21

興味深いふるいは二次ふるいです。これは、数論-二次合同法、およびいくつかの線形代数を使用します。大学2年次の数論コースで使えるくらいに勉強しました。
タナー

33

@ヤスキー

除数関数には、完全な正方形に対して正しく機能しないというバグがあります。

試してください:

int divisors(int x) {
    int limit = x;
    int numberOfDivisors = 0;

    if (x == 1) return 1;

    for (int i = 1; i < limit; ++i) {
        if (x % i == 0) {
            limit = x / i;
            if (limit != i) {
                numberOfDivisors++;
            }
            numberOfDivisors++;
        }
    }

    return numberOfDivisors;
}

6
(x%i)は、i = 0のときにゼロで除算しませんか?i = 1..limitにする必要がありますか?
rhu

@rhu 0は任意の数値の要素ではないため、0をチェックしても意味がありません。
EJoshuaS-モニカを

29

アトキンのふるいが進むべき道であることに私は同意しません。なぜなら、素数について[1、n]のすべての数をチェックすることは、除算によって数を減らすよりも簡単に時間がかかるからです。

少しハッカーではありますが、一般的にはるかに高速なコードを次に示します。

import operator
# A slightly efficient superset of primes.
def PrimesPlus():
  yield 2
  yield 3
  i = 5
  while True:
    yield i
    if i % 6 == 1:
      i += 2
    i += 2
# Returns a dict d with n = product p ^ d[p]
def GetPrimeDecomp(n):
  d = {}
  primes = PrimesPlus()
  for p in primes:
    while n % p == 0:
      n /= p
      d[p] = d.setdefault(p, 0) + 1
    if n == 1:
      return d
def NumberOfDivisors(n):
  d = GetPrimeDecomp(n)
  powers_plus = map(lambda x: x+1, d.values())
  return reduce(operator.mul, powers_plus, 1)

psこれは、この問題を解決するためのpythonコードです。


11

以下は、単純なO(sqrt(n))アルゴリズムです。私はこれを使用して、プロジェクトのオイラーを解決しました

def divisors(n):
    count = 2  # accounts for 'n' and '1'
    i = 2
    while i ** 2 < n:
        if n % i == 0:
            count += 2
        i += 1
    if i ** 2 == n:
        count += 1
    return count

しかし、なぜ常にカウントを2ずつ増やすのですか?...適用した定理はありますか?
SummerCode、2015年

3
sqrt(n)までしかcontingしていないからです。例:36のすべての約数を見つけようとしている場合-2から6まで数えます。1&36、2&18、3&12、4&9、6、6はすべて約数であり、ペアになっています。
アントニー・トーマス

2
アンソニーに感謝します、私は今理解しました:D!小さな補遺:私は今のところ、それは代わりに1を考慮に2回それを取るので、それは別途のsqrt(n)の値を扱うべきだと思う、私は考える
SummerCode

O(sqrt(n))は悪くありませんが、最適ではありません。素因数分解の計算ははるかに速く実行でき、除数の数を計算するには十分です。
le_m 2017年

各反復でi²を計算する必要があります。iを√n(1回だけ計算)と比較する方が速くありませんか?
ユクレレ

10

この興味深い質問は見た目よりもはるかに難しく、答えられていません。質問は2つの非常に異なる質問に分解できます。

1与えられたN、Nの素因数のリストLを見つける

2を与えられたL、一意の組み合わせの数を計算

私がこれまでに見たすべての回答は#1を参照しており、膨大な数の場合は扱いにくいとは言えません。適度なサイズのN、64ビットの数値でも簡単です。巨大なNの場合、因数分解の問題は「永遠に」かかります。公開鍵の暗号化はこれに依存しています。

質問2については、さらに議論が必要です。Lに一意の数値のみが含まれている場合、これは、n個のアイテムからk個のオブジェクトを選択するための組み合わせ式を使用した単純な計算です。実際には、kを1からsizeof(L)まで変化させながら、式を適用した結果を合計する必要があります。ただし、Lには通常、複数の素数が複数出現します。たとえば、L = {2,2,2,3,3,5}はN = 360の因数分解です。この問題は非常に困難です。

#2を繰り返します。コレクションAにk個のアイテムが含まれ、アイテムaにはa 'の重複があり、アイテムbにはb'の重複があるなどです。1〜k-1アイテムの一意の組み合わせはいくつありますか?たとえば、{2}、{2,2}、{2,2,2}、{2,3}、{2,2,3,3}は、L = {2,2の場合、それぞれ1回だけ出現する必要があります、2,3,3,5}。このような一意のサブコレクションはそれぞれ、サブコレクション内のアイテムを乗算することにより、Nの一意の約数です。


ここでは2と非常に同様の問題のためのいくつかの擬似コードへのリンクですanswers.google.com/answers/threadview/id/392914.html
mR_fr0g

3
質問#2にはよく知られている解決策があります。{p_i、k_i}の因数分解の場合、p_ik_i多重度を持つ数の素因数であり、その数の約数の総数は(k_1+1)*(k_2+1)*...*(k_n+1)です。もうご存知だと思いますが、ここにランダムリーダーがいる場合のために、これを書き留めておきます。
ネスは

9

あなたの質問への答えは、整数のサイズに大きく依存します。100ビット未満などの小さい数の方法と、(暗号化で使用されるような)1000ビット以下の数の方法は完全に異なります。


6


ちょうど1行私はあなたの質問を非常に慎重に考え、非常に効率的でパフォーマンスの高いコードを書き込もうとしました。画面に指定された数値のすべての約数を印刷するには、1行のコードが必要です!(gccを介したコンパイル中にオプション-std = c99を使用)

for(int i=1,n=9;((!(n%i)) && printf("%d is a divisor of %d\n",i,n)) || i<=(n/2);i++);//n is your number

除数の数を見つけるには、次の非常に高速な関数を使用できます(1と2を除くすべての整数に対して正しく機能します)

int number_of_divisors(int n)
{
    int counter,i;
    for(counter=0,i=1;(!(n%i) && (counter++)) || i<=(n/2);i++);
    return counter;
}

または与えられた数を除数として扱う場合(1と2を除くすべての整数に対して正しく機能します)

int number_of_divisors(int n)
{
    int counter,i;
    for(counter=0,i=1;(!(n%i) && (counter++)) || i<=(n/2);i++);
    return ++counter;
}

注:上記の2つの関数は、1と2を除くすべての正の整数に対して正しく機能するため、2より大きいすべての数に対して機能しますが、1と2をカバーする必要がある場合は、次の関数のいずれかを使用できます(少しもっとゆっくり)

int number_of_divisors(int n)
{
    int counter,i;
    for(counter=0,i=1;(!(n%i) && (counter++)) || i<=(n/2);i++);
    if (n==2 || n==1)
    {
    return counter;
    }
    return ++counter;
}

または

int number_of_divisors(int n)
{
    int counter,i;
for(counter=0,i=1;(!(i==n) && !(n%i) && (counter++)) || i<=(n/2);i++);
    return ++counter;
}

小さな美しいです:)


5

アトキンのふるいは、与えられた整数までのすべての素数を与えるエラトステネスのふるいの最適化されたバージョンです。詳細については、これをグーグルできるはずです。

そのリストを取得したら、それを正確な除数であるかどうか(つまり、剰余がゼロであるかどうか)を確認するために、各素数で数値を除算するのは簡単なことです。

数値(n)の約数を計算する基本的な手順は次のとおりです[これは実際のコードから変換された疑似コードなので、エラーが発生していないことを願っています]:

for z in 1..n:
    prime[z] = false
prime[2] = true;
prime[3] = true;

for x in 1..sqrt(n):
    xx = x * x

    for y in 1..sqrt(n):
        yy = y * y

        z = 4*xx+yy
        if (z <= n) and ((z mod 12 == 1) or (z mod 12 == 5)):
            prime[z] = not prime[z]

        z = z-xx
        if (z <= n) and (z mod 12 == 7):
            prime[z] = not prime[z]

        z = z-yy-yy
        if (z <= n) and (x > y) and (z mod 12 == 11):
            prime[z] = not prime[z]

for z in 5..sqrt(n):
    if prime[z]:
        zz = z*z
        x = zz
        while x <= limit:
            prime[x] = false
            x = x + zz

for z in 2,3,5..n:
    if prime[z]:
        if n modulo z == 0 then print z

5

あなたはこれを試すかもしれません。少しハックですが、かなり高速です。

def factors(n):
    for x in xrange(2,n):
        if n%x == 0:
            return (x,) + factors(n/x)
    return (n,1)

2
この関数は妥当な時間でnの素因数分解を提供しますが、それはa)最適ではなく、b)OPの質問に従って指定された数の約数を計算しません
le_m

そして、その再帰のため、大きな数では機能しません
whackamadoodle3000 '25 / 02/25

これは最適ではなく、係数を数えるのではなく、実際それらをリストしますが、これのシンプルさと美しさは驚くべきものであり、かなり高速です。^^
Gaurav Singhal

5

素因数分解を行ったら、除数の数を見つける方法があります。個々の因子のそれぞれの指数に1を加算してから、指数を乗算します。

例:36素因数分解:2 ^ 2 * 3 ^ 2除数:1、2、3、4、6、9、12、18、36除数の数:9

各指数に1を加算2 ^ 3 * 3 ^ 3指数を乗算:3 * 3 = 9


3

ソリューションに取り組む前に、通常のケースではSieveアプローチが適切な答えではない可能性があることを考慮してください。

しばらく前に主要な質問があり、私は時間テストを行いました-少なくとも素数であるかどうかを決定する32ビット整数は、総当たりよりも遅いかどうかを決定しました。進行中の2つの要因があります。

1)人間は除算を行うのにしばらく時間がかかりますが、コンピューターでの処理は非常に高速です。これは、答えを調べるコストと同じです。

2)プライムテーブルがない場合は、L1キャッシュで完全に実行されるループを作成できます。これはそれをより速くします。


3

これは効率的なソリューションです。

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

2

除数は見事な何かを行います:彼らは完全に分割します。除数の数をチェックしたい場合nは、スペクトル全体をスパンすることは明らかに冗長1...nです。私はこれについて詳細な調査を行っていませんが、三角形の数に関するProject Eulerの問題12を解決しました。500を超える除数テストに対する私のソリューションは、309504マイクロ秒(約0.3秒)実行されました。ソリューションのためにこの除数関数を書きました。

int divisors (int x) {
    int limit = x;
    int numberOfDivisors = 1;

    for (int i(0); i < limit; ++i) {
        if (x % i == 0) {
            limit = x / i;
            numberOfDivisors++;
        }
    }

    return numberOfDivisors * 2;
}

どのアルゴリズムにも、弱点があります。これは素数に対して弱いと思いました。しかし、三角形の数字は印刷されないため、その目的を完全に果たしました。私のプロファイリングから、それはかなりうまくいったと思います。

幸せな休日。


1
ここでは、最初の反復で0による除算が行われます
barfoon

残念ながら違います。++ iはi ++とは異なります(ゼロ除算エラーが発生します)
iGbanam

私はあなたの関数をPHPで記述して実行しました
barfoon

奇妙な理由で、これは完璧に機能しました。まあ、私の悪い。開始numberOfDivisorsし、イテレータを1にします。これにより、ゼロ除算エラーが解消されます
iGbanam '21 / 10/21

1
あなたのアルゴリズムは完全な正方形では機能しません。たとえば、2を2回カウントしているため、入力x = 4に対して4を返します... 1、2、2、4です。答えは3である必要があります。3、1、2、4
Michael

1

ここで説明されているアトキンのふるいが必要です。http//en.wikipedia.org/wiki/Sieve_of_Atkin


1
それはあなたの与えられた数よりも少ない素数をあなたに与えるでしょう-しかし、それらの素数が約数になるであろうという保証はありませんか?(何か不足している場合を除きます)
Andrew Edgecombe

それは均等にN.を分割するすべての素数<SQRT(N)を求めるためにここからの迅速な飛躍だ
SquareCog

1
素早い飛躍かもしれませんが、すべての素数<sqrt(N)をテストすることは、どれほど効率的にそれらを見つけても、依然として悪い因数分解手法です。それを改善する方法はたくさんあります。
user11318 '09 / 09/21

素数のテストはO(N)であり、難しい部分である素数を見つけることです。しかし、エラトステインの最適化されていないふるいを使用しても、1秒未満で数百万未満のすべての素数を見つけることができます。これは64bの数値をカバーしており、ここでは暗号レベルの要素の分解については
触れ

1

素数法はここで非常に明確です。P []はsq = sqrt(n)以下の素数のリストです。

for (int i = 0 ; i < size && P[i]<=sq ; i++){
          nd = 1;
          while(n%P[i]==0){
               n/=P[i];
               nd++;
               }
          count*=nd;
          if (n==1)break;
          }
      if (n!=1)count*=2;//the confusing line :D :P .

     i will lift the understanding for the reader  .
     i now look forward to a method more optimized  .

1

数論の教科書は、除数を数える関数をタウと呼びます。最初の興味深い事実は、それが乗法的であるということです。τ(ab)=τ(a)τ(b)(aとbに共通因子がない場合)。(証明:aとbの約数の各ペアはabの個別の約数を与える)。

ここで、pa素数の場合、τ(p ** k)= k + 1(pのべき乗)であることに注意してください。したがって、因数分解からτ(n)を簡単に計算できます。

ただし、大きな数の因数分解は遅くなる可能性があります(RSA crytopraphyのセキュリティは、2つの大きな素数の積が因数分解しにくいことに依存します)。これは、この最適化されたアルゴリズムを示唆しています

  1. 数が素数(速い)かどうかをテストする
  2. もしそうなら、2を返す
  3. それ以外の場合は、数を因数分解します(複数の大きな素因数がある場合は遅くなります)
  4. 因数分解からτ(n)を計算する

1

以下は、与えられた数の約数を見つけるCプログラムです。

上記のアルゴリズムの複雑さはO(sqrt(n))です。

このアルゴリズムは、完全な正方形ではない数値だけでなく、完全な正方形ではない数値でも正しく機能します。

アルゴリズムが最も効率的になるように、ループの上限は数値の平方根に設定されていることに注意してください。

上限を別の変数に格納すると時間も節約できることに注意してください。forループの条件セクションでsqrt関数を呼び出さないでください。これにより、計算時間が節約されます。

#include<stdio.h>
#include<math.h>
int main()
{
    int i,n,limit,numberOfDivisors=1;
    printf("Enter the number : ");
    scanf("%d",&n);
    limit=(int)sqrt((double)n);
    for(i=2;i<=limit;i++)
        if(n%i==0)
        {
            if(i!=n/i)
                numberOfDivisors+=2;
            else
                numberOfDivisors++;
        }
    printf("%d\n",numberOfDivisors);
    return 0;
}

上記のforループの代わりに、次のループを使用することもできます。これにより、数値の平方根を見つける必要がなくなるため、さらに効率的です。

for(i=2;i*i<=n;i++)
{
    ...
}

1

これが私が書いた関数です。最悪の時間の複雑さはO(sqrt(n))です。一方、最良の時間はO(log(n))です。それはあなたにその発生回数とともにすべての素数を与えます。

public static List<Integer> divisors(n) {   
    ArrayList<Integer> aList = new ArrayList();
    int top_count = (int) Math.round(Math.sqrt(n));
    int new_n = n;

    for (int i = 2; i <= top_count; i++) {
        if (new_n == (new_n / i) * i) {
            aList.add(i);
            new_n = new_n / i;
            top_count = (int) Math.round(Math.sqrt(new_n));
            i = 1;
        }
    }
    aList.add(new_n);
    return aList;
}

この関数の計算結果はわかりませんが、nの約数のリストではありません。
le_m

1

これは、数の除数を計算する最も基本的な方法です。

class PrintDivisors
{
    public static void main(String args[])
    {

    System.out.println("Enter the number");

    // Create Scanner object for taking input
    Scanner s=new Scanner(System.in);

    // Read an int
    int n=s.nextInt();

        // Loop from 1 to 'n'
        for(int i=1;i<=n;i++)
        {

            // If remainder is 0 when 'n' is divided by 'i',
            if(n%i==0)
            {
            System.out.print(i+", ");
            }
        }

    // Print [not necessary]    
    System.out.print("are divisors of "+n);

    }
}

1

ケンドール

私はあなたのコードをテストしていくつかの改善を行いましたが、今ではさらに高速になっています。私も@هومنجاویدپورコードでテストしましたが、これは彼のコードよりも高速です。

long long int FindDivisors(long long int n) {
  long long int count = 0;
  long long int i, m = (long long int)sqrt(n);
  for(i = 1;i <= m;i++) {
    if(n % i == 0)
      count += 2;
  }
  if(n / m == m && n % m == 0)
    count--;
  return count;
}

0

これは数を因数分解するだけの問題ではありませんか?数のすべての因数を決定しますか?次に、1つ以上の要素のすべての組み合わせが必要かどうかを決定できます。

したがって、1つの可能なアルゴリズムは次のようになります。

factor(N)
    divisor = first_prime
    list_of_factors = { 1 }
    while (N > 1)
        while (N % divisor == 0)
            add divisor to list_of_factors
            N /= divisor
        divisor = next_prime
    return list_of_factors

その後、残りの答えを決定するために要因を組み合わせるのはあなた次第です。


0

これは私がジャスティンの答えに基づいて思いついたものです。最適化が必要な場合があります。

n=int(input())

a=[]
b=[]

def sieve(n):
    np = n + 1
    s = list(range(np)) 
    s[1] = 0
    sqrtn = int(n**0.5)
    for i in range(2, sqrtn + 1): 
        if s[i]:
            s[i*i: np: i] = [0] * len(range(i*i, np, i))
    return filter(None, s)

k=list(sieve(n))

for i in range(len(k)):
        if n%k[i]==0:
                a.append(k[i])

a.sort()

for i in range(len(a)):
        j=1
        while n%(a[i]**j)==0: 
                j=j+1
        b.append(j-1)

nod=1

for i in range(len(b)):
        nod=nod*(b[i]+1)

print('no.of divisors of {} = {}'.format(n,nod))

0

これはあなたが探しているものだと思います。それをコピーし、メモ帳に貼り付けます。*。bat.Run.Enter Number。

Plsは、CMD変数は999999999を超える値をサポートできないことに注意してください

@echo off

modecon:cols=100 lines=100

:start
title Enter the Number to Determine 
cls
echo Determine a number as a product of 2 numbers
echo.
echo Ex1 : C = A * B
echo Ex2 : 8 = 4 * 2
echo.
echo Max Number length is 9
echo.
echo If there is only 1 proces done  it
echo means the number is a prime number
echo.
echo Prime numbers take time to determine
echo Number not prime are determined fast
echo.

set /p number=Enter Number : 
if %number% GTR 999999999 goto start

echo.
set proces=0
set mindet=0
set procent=0
set B=%Number%

:Determining

set /a mindet=%mindet%+1

if %mindet% GTR %B% goto Results

set /a solution=%number% %%% %mindet%

if %solution% NEQ 0 goto Determining
if %solution% EQU 0 set /a proces=%proces%+1

set /a B=%number% / %mindet%

set /a procent=%mindet%*100/%B%

if %procent% EQU 100 set procent=%procent:~0,3%
if %procent% LSS 100 set procent=%procent:~0,2%
if %procent% LSS 10 set procent=%procent:~0,1%

title Progress : %procent% %%%



if %solution% EQU 0 echo %proces%. %mindet% * %B% = %number%
goto Determining

:Results

title %proces% Results Found
echo.
@pause
goto start

882161280 - 1282個の約数
dondon


0

これらの線に沿って何かを試してください:

int divisors(int myNum) {
    int limit = myNum;
    int divisorCount = 0;
    if (x == 1) 
        return 1;
    for (int i = 1; i < limit; ++i) {
        if (myNum % i == 0) {
            limit = myNum / i;
            if (limit != i)
                divisorCount++;
            divisorCount++;
        }
    }
    return divisorCount;
}

-1

最も効率的な方法はわかりませんが、次のようにします。

  • 素数の表を作成して、数値の平方根以下のすべての素数を見つけます(個人的には、アトキンのふるいを使用します)
  • 数の平方根以下のすべての素数を数え、2を掛けます。数値の平方根が整数の場合、カウント変数から1を引きます。

動作するはずです\ o /

必要に応じて、明日Cで何かをコーディングして説明することができます。


2
よくわかりません。ある数の平方根よりも小さいすべての素数を数えると、それは約数になりません...数の平方根よりも小さいすべての素数がその数の約数になるわけではありません。
Garrett Berg
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.