Algoritma belirli bir sayıda bölenler sayısını hesaplamak için

oy
163

Verilen sayının bölenler sayısını hesaplamak için en uygun algoritma (epeyce) ne olurdu?

Eğer pseudocode veya bazı örnek bir bağlantı sağlayabilir olursanız harika olacak.

DÜZENLEME: Tüm cevaplar çok yararlı olmuştur, teşekkür ederim. Ben Atkin ait Sieve uygulayan ediyorum ve sonra Jonathan Leffler belirtilen ne benzer bir şey kullanmak için gidiyorum. Justin Bozonier tarafından gönderildi bağlantı istediğim konusunda daha fazla bilgi vardır.

Oluştur 21/09/2008 saat 06:44
kaynak kullanıcı
Diğer dillerde...                            


28 cevaplar

oy
1

Sen Atkin Elek, burada açıklanan istiyorum: http://en.wikipedia.org/wiki/Sieve_of_Atkin

Cevap 21/09/2008 saat 06:53
kaynak kullanıcı

oy
0

Sayının tüm faktörler belirleyici - sayısını değil Faktoring bu sadece bir soru var mı? Bir veya daha fazla faktörlerin hepsini kombinasyonları gerekli olup olmadığını karar verebilirsiniz.

Yani, olası bir algoritma olacaktır:

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

Daha sonra size kalmış cevap kalanını belirlemek için faktörlerin birleştirmektir.

Cevap 21/09/2008 saat 06:59
kaynak kullanıcı

oy
74

Dmitriy Asal listesini oluşturmak için Atkin arasında Elek isteyeceksiniz fakat bunun her konuda ilgilenir inanmıyorum haklı. Şimdi asal bir listesi var size bir bölen (ve ne sıklıkta) olarak hareket nasıl bu asal çoğunu görmek gerekir.

İşte algo için bazı piton Buraya bak ": - Gerek bölenler algoritma matematik Konu" ve arayın. Sadece bununla onları dönen yerine listedeki öğelerin sayısını saymak.

İşte Doktor Matematik var bunu matematiksel olarak yapmanız gereken tam olarak ne açıklar.

Esasen numaralı ise aşağı kaynar n: olduğu
n = a^x * b^y * c^z
sonra Bölen için toplam sayısı (a, b ve c, n en asal bölenler ve y, y olduğu ve z bu bölen tekrarlanır sayısıdır):
(x + 1) * (y + 1) * (z + 1).

Düzenleme: BTW, bunu doğru anlamak ediyorsam açgözlü bir algo ne miktarda yapmak isteyeceğiniz a, b, c, vb bulmak için. senin büyük asal bölen ile başlayın ve n sayısını aşacaktır bir başka çarpma kadar kendisi ile çarpın. Daha sonra bir sonraki en düşük faktör ve zamanlara mevcut asal ile çarpılarak kez önceki asal ^ numarasını taşımak ve sonraki aşan n olacak kadar asal ile çarpılması tutmak ... vb çarpın kaç kez takip edin bölenler birlikte ve yukarıda formül olarak bu numara uygulanır.

Değil 100 Benim algo açıklaması hakkında emin% ama bu değilse benzer bir şey.

Cevap 21/09/2008 saat 07:03
kaynak kullanıcı

oy
-1

Ben EN etkili bir yöntem bilmiyorum, ama şunları yapardım:

  • (Ben Atkin ait Elek kullanmayı tercih ediyorum, şahsen) Tüm daha az veya sayının kare köküne eşittir asal bulmak için asal bir tablo oluşturun
  • tümünden daha az ya da sayının kare köküne eşittir hazırladığını sayın ve iki ile çarpın. sayının karekökü bir tam sayı ise, o sayım değişken bir çıkartın.

\ O / çalışmalıdır

Eğer gerekiyorsa, göstermek için C yarın bir şeyler kod.

Cevap 21/09/2008 saat 07:16
kaynak kullanıcı

oy
5

Atkin elek verilen bir tam sayıya tüm asal sayıları veren Eratosthenes eleğin optimize edilmiş bir sürümüdür. Daha detaylı bilgi için bu google gerekir.

O liste var sonra, kesin bir bölen olup olmadığını görmek için her asal tarafından numaranızı bölmek için basit bir mesele (yani kalan sıfırdır) bulunuyor.

Bir dizi (n) için bölenler hesaplanırken temel adımlar [bu yalancı kod bu yüzden hatalar teşkil etmediğinden umut gerçek koddan dönüştürülür] şunlardır:

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
Cevap 21/09/2008 saat 07:36
kaynak kullanıcı

oy
46

Bir var çok Atkin ait elek daha faktoring daha teknikleri. Örneğin Şimdi meydanlarda ürünü olarak 5893 yazmaya çalışacağım ... onun sqrt 76.76 olduğu Eh 5893. faktör istediğinizi varsayalım. İyi (77 * 77-5893) = kare 6 36, bu nedenle 5893 = 77 * 77-6 * 6 = (77 + 6) (77-6) = 83 * 71. 5893 tamkare olduğu - o çalıştı olmasaydı biz * 78 78 olsun bakmış olur. Ve bunun gibi. Bu teknik ile hızlı kare köküne yakın faktörler için n çok daha hızlı bireysel asal test ederek daha test edebilirsiniz. Eğer bir elek ile büyük asal ekarte etmede bu tekniği birleştiren, yalnız elek ile çok daha iyi bir faktoring yöntemine sahip olacaktır.

Ve bu sadece geliştirilmiştir teknikler çok sayıda biridir. Bu oldukça basit bir tanesidir. Size eliptik eğriler dayalı faktoring tekniklerini anlamak için, diyelim ki, yeterli sayı teorisi öğrenmek için uzun bir zaman alacaktır. (Onların var biliyorum. Onları anlamıyorum.)

Bu nedenle küçük tamsayılar ile ilgileniyor sürece, o sorunu kendim çözmeye olmaz. Bunun yerine ben gibi bir şey kullanmak için bir yol bulmaya çalışacaktı PARI zaten uygulanan bir yüksek verimli çözümü vardır kütüphanede. Bunun üzerine ben yaklaşık 0,05 saniyede 124321342332143213122323434312213424231341 gibi rastgele 40 haneli bir sayı faktör olabilir. (Onun çarpanlara ayırma, sen merak durumda olan 29 * * 1321 439 * 157907 * 284749 * 33843676813 * 4857795469949 . Ben Atkin ait elek kullanılarak bu anlamaya vermedi oldukça eminim ...)

Cevap 21/09/2008 saat 09:47
kaynak kullanıcı

oy
9

Sorunuza bir cevap tamsayı büyüklüğüne büyük ölçüde bağlıdır. az sayıda, örneğin az 100 bit için yöntemler ve numaralar için -1000 bit (örneğin kriptografide kullanıldığı gibi) tamamen farklıdır.

Cevap 21/09/2008 saat 19:38
kaynak kullanıcı

oy
27

Ben kolayca bölünmeler sayısını azaltmak için it would daha primality için [1, n] her sayısını kontrol etmek uzun sürebilir çünkü Atkin elek, gitmek yolu olduğunu katılmıyorum.

Burada biraz hackier, genellikle çok daha hızlı olmasına rağmen, bazı kod:

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 piton kodunu çalışıyor bu sorunu çözmek için.

Cevap 23/09/2008 saat 02:53
kaynak kullanıcı

oy
10

Bu ilginç bir soru göründüğünden çok daha zor olduğunu ve cevap edilmemiştir. Soru 2 çok farklı sorular bunlar hesaba katılabilir.

N verilen 1, N'in asal faktörlerin listesi L bulmak

2 belli bir L, eşsiz kombinasyonların sayısını hesaplamak

Tek gördüğüm cevaplar şu ana kadar 1. bakın ve muazzam numaraları için uysal değil söz etmiyorlar. orta büyüklükteki N için, hatta 64-bitlik sayı, bu kolaydır; muazzam N için, faktoring problemi "sonsuza dek" alabilir. Genel anahtar şifreleme buna bağlıdır.

Soru 2 daha fazla tartışma ihtiyacı var. L yalnızca benzersiz sayılar içeriyorsa, bu n öğelerden k nesneleri seçmek için kombinasyon formülünü kullanarak basit bir hesaplama olduğunu. Aslında, sizeof (L) 1 k değiştirilerek formül uygulanarak sonuçları toplamak gerekir. Bununla birlikte, L, genellikle birden fazla asal birden fazla kopyasını içerecektir. Örneğin, L = {2,2,2,3,3,5} Şimdi bu sorun oldukça zordur N = 360. çarpanlara olduğunu!

vb 1 kaç benzersiz kombinasyonları k-1'e öğeleri olup Tekrarlamamız 2. k öğeleri içeren koleksiyon C verilmiş, öyle ki öğe bir bir 'çiftleri ve öğe B B bulunur vardır çiftleri? Örneğin, {2}, {2,2}, {2,2,2}, {2,3}, {2,2,3,3} Her yalnızca bir kez meydana gerekir, L = {2,2 , 2,3,3,5}. Her tür benzersiz bir alt toplama alt koleksiyonunda öğeleri çarparak N eşsiz bölen olduğunu.

Cevap 04/11/2008 saat 03:52
kaynak kullanıcı

oy
5

Sen bunu deneyebilirsiniz. Biraz hackish, ama makul hızlı.

def factors(n):
    for x in xrange(2,n):
        if n%x == 0:
            return (x,) + factors(n/x)
    return (n,1)
Cevap 18/07/2009 saat 04:31
kaynak kullanıcı

oy
3

Eğer bir çözüme üretmeden önce Elek yaklaşım tipik durumda iyi bir cevap olmayabilir düşünüyoruz.

Bir süre önce bir asal soru vardı ve ben bir zaman test yaptım - en azından belirleyici 32 bitlik tamsayılar için asal kaba kuvvet daha yavaş olduğunu olsaydı. oluyor iki faktör vardır:

Bir insan bir bölünme yapmak biraz zaman alıyor olsa 1) onlar bilgisayarda çok hızlı - cevap ararken maliyetine benzer.

2) Eğer L1 önbelleği tamamen çalışan bir döngü yapabilir Başbakan tablo yoksa. Bu hızlandırır.

Cevap 18/07/2009 saat 05:11
kaynak kullanıcı

oy
5

Asal çarpanlara sahip olduktan sonra, bölenler sayısını bulmak için bir yol yoktur. Her bir faktörüne üstlerin her birine bir tane ekleyin ve sonra birlikte üstellerini çarpın.

36 Asal Ayrışımı: Örneğin: 2 ^ 2 * 3 ^ 2 Bölenler: 1, 2, 3, 4, 6, 9, 12, 18, Bölen 36 sayısı: 9

3 * 3 = 9: Her bir üsse 2 ^ 3 * 3 ^ 3 çarp üsler için birini ekleyin

Cevap 02/02/2010 saat 01:28
kaynak kullanıcı

oy
2

Bölenler muhteşem bir şey yapmak: tamamen bölün. Eğer bir numara için bölenler sayısını kontrol etmek isterseniz, n, açıkça, geniş bir yelpazeyi kapsamaktadır gereksiz olduğunu 1...n. Bunun için herhangi derinlemesine araştırma yapmadım ama çözüldü Üçgen Numaraları Proje Euler sorunu 12 . Benim çözüm daha sonra 500 bölenler testi 309504 mikrosaniye (~ 0.3s) için koştu. Ben çözüm için bu bölen fonksiyon yazdım.

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

Her algoritma için, zayıf bir nokta vardır. Bu asal sayılar karşısında zayıf olduğunu düşünüyorum. Üçgen sayılar yazdırmak olmadığı için Ancak, kusursuz amacına hizmet. Benim profilleme göre, bu durumda oldukça iyi yaptığını düşünüyorum.

Mutlu tatiller.

Cevap 30/12/2010 saat 22:19
kaynak kullanıcı

oy
33

@Yasky

Kişisel bölenler işlevi mükemmel kareler için doğru çalışmadığını bir hata içinde bulunmaktadır.

Deneyin:

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;
}
Cevap 23/03/2011 saat 15:32
kaynak kullanıcı

oy
6

SADECE bir satır
senin soru hakkında çok dikkat düşündüm ve biz kod sadece bir satır gerek ekranda belirli bir sayının tüm bölenler yazdırmak için kod yüksek verimli ve performanslı bir parça yazmaya çalıştık! (gcc aracılığıyla derlenirken kullanım seçeneği = C99 -std)

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

bölenler numaralarını bulmak için size (1 ve 2 hariç tüm tamsayı numarası için doğru çalışma) Aşağıdaki çok çok hızlı işlevini kullanabilirsiniz

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

ya da (1 ve 2 dışındaki tüm tam sayı için doğru bir şekilde çalışması) bölen olarak numara verilir tedavi eğer

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

NOT: Yukarıdaki iki fonksiyon sayısı 1 hariç tüm pozitif tam sayısı için düzgün çalışıyor ve 2 yüzden 2'den büyüktür ama 1 ve 2 kapsayacak gerekiyor ise, aşağıdaki işlevlerden birini kullanabilirsiniz tüm numaralar için işlevseldir (biraz Yavaş)

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

VEYA

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

Küçük güzeldir :)

Cevap 11/11/2011 saat 03:59
kaynak kullanıcı

oy
1

asal sayı yöntemi burada çok açıktır. P [] 'dan daha az asal sayı ya da buna eşit kare = sqrt (n)' in bir listesi;

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  .
Cevap 10/01/2013 saat 00:12
kaynak kullanıcı

oy
8

Burada yalındır O (sqrt (n)) algoritmasıdır. Ben çözmek için bu kullanılan Project Euler

def divisors(n):
    count=2 # accounts for 'n' and '1'
    i=2
    while(i**2 < n):
        if(n%i==0):
            count+=2
        i+=1
    count+=(1 if i**2==n else 0)
    return count  
Cevap 05/04/2013 saat 05:32
kaynak kullanıcı

oy
1

Sayı teorisi ders kitapları bölen sayma fonksiyonu tau arayın. İlk ilginç aslında o yani çarpımsal olmasıdır. τ (ab) '= τ (a) τ, (b), a ve b, bir ortak faktör olduğunda. (Test: a ve b bölenler her bir çifti ab farklı bir böleni verir).

Şimdi unutmayın pa asal, t alınmak (p ** k) = k + 1 (p güçler) için. Böylece kolayca factorisation gelen t alınmak (n) hesaplayabilir.

Ancak factorising sayıda (RSA crytopraphy güvenlik factorise zor olmak iki büyük asal ürünü bağlıdır) yavaş olabilir. Yani bu optimize algoritma da anlaşılacağı

  1. Deney numarası asal sayı ise (hızlı)
  2. Eğer öyleyse, 2 dönüş
  3. Aksi takdirde, sayı Factorise (yavaş birden çok büyük asal faktörleri varsa)
  4. factorisation gelen t alınmak (n) değerinin hesaplanması
Cevap 14/07/2013 saat 13:15
kaynak kullanıcı

oy
1

Aşağıdaki belirli bir sayıda bölenler sayısını bulmak için bir Cı programıdır.

Yukarıdaki algoritma karmaşıklığı O (sqrt (n)) 'dir.

Bu algoritma mükemmel kare yanı sıra mükemmel kare olmayan sayılardır sayısı için düzgün çalışacaktır.

döngünün UPPERLIMIT en verimli bir algoritma elde etmek sayının kare köküne ayarlandığını unutmayın.

Ayrı bir değişkende UPPERLIMIT saklanması da zaman kazandırır unutmayın, bu da hesaplama zaman kazandırır, döngü koşulu bölümünde sqrt işlevini çağırmalıdır değil.

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

Bu sayının kare kökünü bulmak ihtiyacını ortadan kaldırır Bunun yerine yukarıdaki döngü için de daha verimli aşağıdaki döngüyü kullanabilirsiniz.

for(i=2;i*i<=n;i++)
{
    ...
}
Cevap 19/08/2014 saat 14:35
kaynak kullanıcı

oy
1

İşte yazdığım bir fonksiyondur. o kötü zaman karmaşıklığı diğer taraftan (sqrt (n)), en iyi zamanı O (log (n)) O bu. Onun oluşum sayısı ile birlikte size tüm asal bölenler verir.

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;
}
Cevap 01/12/2014 saat 13:02
kaynak kullanıcı

oy
3

Bu, etkili bir çözüm:

#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;
}
Cevap 01/12/2014 saat 14:01
kaynak kullanıcı

oy
1

Bu sayı divissors işlem en temel yoludur:

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);

    }
}
Cevap 02/12/2014 saat 03:25
kaynak kullanıcı

oy
0

Bu i Justin Yanıta göre geldi şeydir. Bazı optimizasyon gerektirebilir.

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))
Cevap 29/11/2015 saat 07:30
kaynak kullanıcı

oy
0

Bunun istediğin tam olarak ne yaptığını için istediğiniz.Ben aradığınız olduğunu düşünüyorum. Kopya ve 2 tarafından * .bat.Run.Enter Number.Multiply olarak Notepad.Save süreci yapıştırın ve divisors.I sayısı bilerek böylece daha hızlı bölenler belirlemek belirtti şu:

Pls CMD 999999999 üzerinde olamaz destek değerlerini varriable unutmayın

@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
Cevap 07/02/2016 saat 21:24
kaynak kullanıcı

oy
1

@Kendall

Ben kodunuzu test ve şimdi daha da hızlı olduğunu, bazı iyileştirmeler yaptık. Ben de bu aynı zamanda onun kod daha hızlıdır, جاویدپور kod هومن @ ile test edilmiştir.

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;
}
Cevap 11/11/2016 saat 15:32
kaynak kullanıcı

oy
0

i kesin yanı sıra bu bir kullanışlı olacak sanırım

script.pyton

>>>factors=[ x for x in range (1,n+1) if n%x==0] print len(factors)

Cevap 23/01/2017 saat 15:57
kaynak kullanıcı

oy
0

bu satırlar boyunca bir şey deneyin:

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;
}
Cevap 23/01/2017 saat 16:01
kaynak kullanıcı

oy
0

Sen maksimum olası N Sqaure köküne asal kadar precompute ve bir dizi asal faktörünün üs hesaplayabilir. n bölenler (n = p1 ^ a p2 ^ b p3 ^ c ...) sayısıdır (a + 1), (b + 1) (c + 1) aynı olduğu için asal birleştirmek yolu saymak olarak Bu faktörlerin numaraları (ve bu bölenler sayısını sayar). Eğer asal sayılar precompute, bu çok hızlıdır

Bu yöntemle ilgili daha detaylı bilgi:

https://mathschallenge.net/library/number/number_of_divisors

https://www.math.upenn.edu/~deturck/m170/wk2/numdivisors.html

http://primes.utm.edu/glossary/xpage/tau.html

#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;

int divisors_count(const vector<int>& primes, int n)
{
    int divisors = 1;
    for (int i = 0; i < primes.size(); ++i) {
        int factor = primes[i];
        int factor_exponent = 0;
        while (n % factor == 0) {
            ++factor_exponent;
            n /= factor;
        }
        divisors *= (factor_exponent + 1);
    }
    if (n > 1) 
        return 2*divisors; // prime factor > sqrt(MAX_N)
    return divisors;
}

int main()
{
    const int MAX_N = 1e6;
    int max_factor = sqrt(MAX_N);

    vector<char> prime(max_factor + 1, true);
    for (int i = 3; i <= max_factor; i += 2) {
        if (prime[i]) {
            for (int j = 3*i; j <= max_factor; j += 2*i) {
                prime[j] = false;
            }   
        }
    }

    vector<int> primes;
    primes.reserve(max_factor/2);
    primes.push_back(2);
    for (int i = 3; i <= max_factor; i += 2) {
        if (prime[i]) {
            primes.push_back(i);
        }
    }

    int n;
    while (cin >> n) {
        cout << divisors_count(primes, n) << endl;
    }
}
Cevap 17/12/2017 saat 15:40
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more