Algorytm obliczania liczby dzielników danej liczby

głosy
163

Jaki byłby najbardziej optymalny algorytm (performance-wise), aby obliczyć liczbę dzielników danej liczby?

Będzie wspaniale, gdyby mógł Pan podać Pseudokod lub link do jakiegoś przykładu.

EDIT: Wszystkie odpowiedzi były bardzo pomocne, dziękuję. Ja realizacji sito atkina a potem mam zamiar użyć coś podobnego do tego, co wskazano Jonathan Leffler. Łącze wysłane przez Justin Bozonier zawiera dalsze informacje na temat tego, co chciałem.

Utwórz 21/09/2008 o 06:44
źródło użytkownik
W innych językach...                            


28 odpowiedzi

głosy
1

Chcesz sito atkina, opisane tutaj: http://en.wikipedia.org/wiki/Sieve_of_Atkin

Odpowiedział 21/09/2008 o 06:53
źródło użytkownik

głosy
0

Nie jest to tylko kwestia faktoringu numer - określenie wszystkich czynników liczby? Można wtedy zdecydować, czy trzeba wszystkie kombinacje jednego lub większej liczby czynników.

Tak więc, jednym z możliwych algorytm będzie:

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

To wtedy do ciebie, aby połączyć czynniki, które określają resztę odpowiedzi.

Odpowiedział 21/09/2008 o 06:59
źródło użytkownik

głosy
74

Dmitriy ma rację, że będziesz chciał sito atkina wygenerować listę prime ale nie wierzę, że troszczy się o całej sprawie. Teraz, że masz listę liczb pierwszych trzeba zobaczyć, jak wiele z tych liczb pierwszych działać jako dzielnik (i jak często).

Oto niektóre python dla algo zajrzyj tutaj i wyszukiwania dla „Temat: matematyka - algorytm dzielników potrzebujesz”. Wystarczy policzyć liczbę elementów na liście zamiast zwracania ich jednak.

Oto doktor matematyki , który wyjaśnia, co dokładnie to, co musisz zrobić matematycznie.

Zasadniczo sprowadza się do, jeśli liczba nwynosi:
n = a^x * b^y * c^z
(w którym A, B, i C są N prime dzielnikami, x, y i z oznaczają liczbę razy dzielnik jest powtarzany), wówczas całkowita liczba dla wszystkich dzielników jest:
(x + 1) * (y + 1) * (z + 1),

EDIT: BTW, aby znaleźć, b, c itd będziemy chcieli robić to, co sprowadza się do chciwego algo jeśli mam zrozumienia tego poprawnie. Start z największych głównego dzielnik i pomnożyć przez siebie aż do dalszego rozmnażania przekroczyłaby liczbę n. Następnie przejść do następnego najniższego współczynnika i czasów poprzedniego doskonałą ^ ile razy została pomnożona przez obecnego premiera i zachować pomnożenie przez sile aż do następnego przekroczy n ... itd śledzić liczbę razy pomnożyć dzielnikami razem i stosować te cyfry w powyższym wzorze.

Nie 100% pewny o moim algo opisem, ale jeśli to nie jest to coś podobnego.

Odpowiedział 21/09/2008 o 07:03
źródło użytkownik

głosy
-1

Nie wiem najskuteczniejsza metoda, ale ja wykonać następujące czynności:

  • Utwórz tabelę liczb pierwszych, aby znaleźć wszystkie liczby pierwsze mniejsze lub równe pierwiastek kwadratowy z liczby (Osobiście używam sito atkina)
  • Policz wszystkie liczby pierwsze mniejsze lub równe pierwiastek kwadratowy z liczby i pomnożyć przez dwa. Jeżeli pierwiastek kwadratowy liczby jest liczbą całkowitą, a następnie odejmuje jeden od zmiennej licznika.

Powinien pracować \ o /

Jeśli trzeba, jutro mogę kodować coś w C do demonstracji.

Odpowiedział 21/09/2008 o 07:16
źródło użytkownik

głosy
5

Sito Atkin jest zoptymalizowana wersja sito Eratostenesa której wszyscy liczb pierwszych do określonej liczby całkowitej. Powinieneś być w stanie google to dla bardziej szczegółowo.

Po uzyskaniu tej listy, to prosta sprawa, aby podzielić liczbę przez każdego sile, aby zobaczyć, czy jest to dokładna dzielnik (czyli reszta jest zero).

Podstawowe etapy obliczania dzielniki na liczby (N), są [to pseudokod przekształcony z kodzie, więc nadzieję, że nie wprowadza błędy]

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
Odpowiedział 21/09/2008 o 07:36
źródło użytkownik

głosy
46

Istnieje wiele więcej technik faktoringu niż sito Atkin. Na przykład przypuśćmy, że chcemy czynnik 5893. Dobrze jej sqrt jest 76.76 ... Teraz postaramy się napisać 5893 jako produkt kwadratów. Dobrze (77 * 77 - 5893) = 36, która jest 6 do kwadratu, tak, 5893 = 77 * 77 - 6 * 6 = (77 + 6 ) (77-6) = 83 * 71 . Jeśli to nie zadziałało, że przyjrzeliśmy się, czy 78 * 78 - 5893 był idealny kwadrat. I tak dalej. Dzięki tej technice można szybko przetestować czynników pobliżu pierwiastka kwadratowego n znacznie szybciej niż poprzez testowanie poszczególnych liczb pierwszych. Jeśli połączyć tę technikę do wykluczenia dużych liczb pierwszych przez sito, trzeba będzie o wiele lepsze metody faktoringu niż z samym sito.

A to tylko jedna z wielu technik, które zostały opracowane. Jest to dość prosty. zajęłoby Ci dużo czasu, aby dowiedzieć się, powiedzmy, tyle teorii liczb do zrozumienia technik faktoringowych oparte na krzywych eliptycznych. (Wiem, że one istnieją. Ja ich nie rozumieją.)

Dlatego chyba że masz do czynienia z małymi liczbami całkowitymi, nie starają się rozwiązać ten problem samodzielnie. Zamiast tego chciałbym spróbować znaleźć sposób na wykorzystanie coś jak PARI biblioteki, która już posiada bardzo wydajne rozwiązanie wdrożone. Dzięki, że mogę czynnik losowy numer 40 cyfrowy jak 124321342332143213122323434312213424231341 w około 0,05 sekundy. (Jego faktoryzacji, w przypadku, gdy zastanawiał się, to * 439 * 29 * 1321 * 284749 157907 * 33843676813 * 4857795469949. Jestem całkiem pewien, że to nie wymyślimy stosując sito atkina ...)

Odpowiedział 21/09/2008 o 09:47
źródło użytkownik

głosy
9

Odpowiedź na to pytanie zależy w dużej mierze od wielkości całkowitej. Metody małe ilości, na przykład mniej niż 100 transmisji, numery ~ 1000 bitów (takie jak stosowane w kryptografii) są całkowicie różne.

Odpowiedział 21/09/2008 o 19:38
źródło użytkownik

głosy
27

Nie zgadzam się, że sito atkina jest droga, bo równie dobrze może to trwać dłużej, by sprawdzić każdy numer w [1, n] dla pierwszości niż miałoby to zmniejszyć liczbę podziałami.

Oto niektóre kod, który, choć nieznacznie hackier, jest na ogół znacznie szybciej:

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 To działa kod Pythona, aby rozwiązać ten problem.

Odpowiedział 23/09/2008 o 02:53
źródło użytkownik

głosy
10

To ciekawe pytanie jest o wiele trudniejsze niż to wygląda, i to nie zostało odebrane. Pytanie może zostać uwzględniona 2 bardzo różnych pytań.

1 podano N, znaleźć listę L czynniki pierwsze 'n'

2 podano L obliczyć liczbę unikalnych kombinacjach

Wszystkie odpowiedzi widzę tak daleko patrz nr 1 i nie wspomnieć, że nie jest podatny na ogromnych ilościach. Dla umiarkowanie wielkości N, nawet liczb 64-bitowych, to jest łatwe; dla ogromnej N, problem faktoring może trwać „wiecznie”. Szyfrowanie kluczem publicznym polega na tym.

Pytanie nr 2 potrzebuje więcej dyskusji. Jeśli L zawiera tylko unikatowe numery, jest to proste obliczenie za pomocą wzoru szyfrowy wyborze przedmiotów k z n elementów. Faktycznie, trzeba zsumować wyniki z zastosowaniem wzoru przy zmienianiu k od 1 do sizeof (L). Jednak L zazwyczaj zawierają wiele wystąpień wielu liczb pierwszych. Na przykład, L = {2,2,2,3,3,5} odpowiada na czynniki n = 360. Obecnie problem ten jest bardzo trudne!

Przekształcenie # 2, biorąc pod uwagę zbiór C zawierający elementy k, tak, że punkt a ma „duplikatów, a pozycja b b” ma duplikatów itp ilu unikalnych kombinacji 1 do K-1 pozycji istnieją? Na przykład, {2}, {2,2}, {2,2,2}, {2,3}, {2,2,3,3} musi każdy, występuje tylko raz, gdy L = {2,2 , 2,3,3,5}. Każdy taki wyjątkowy sub-kolekcja jest wyjątkowa dzielnik N przez pomnożenie elementów w sub-kolekcji.

Odpowiedział 04/11/2008 o 03:52
źródło użytkownik

głosy
5

Można próbować ten jeden. To trochę hackish, ale jest to dość szybko.

def factors(n):
    for x in xrange(2,n):
        if n%x == 0:
            return (x,) + factors(n/x)
    return (n,1)
Odpowiedział 18/07/2009 o 04:31
źródło użytkownik

głosy
3

Przed zobowiązać się do rozwiązania uważają, że podejście Sito może nie być dobrą odpowiedzią w typowym przypadku.

Jakiś czas temu było prime pytanie i zrobiłem próbę czasu - dla 32-bitowych liczb całkowitych przynajmniej określających, czy to premier był wolniejszy niż brute force. Istnieją dwa czynniki dzieje:

1) Podczas gdy człowiek zajmuje trochę czasu, aby zrobić podział są bardzo szybkie na komputerze - podobny do kosztu patrząc odpowiedź.

2) Jeśli nie masz doskonałą tabelę można zrobić pętlę, która przebiega w całości w pamięci podręcznej L1. To sprawia, że ​​szybciej.

Odpowiedział 18/07/2009 o 05:11
źródło użytkownik

głosy
5

Raz masz na czynniki pierwsze, nie ma sposobu, aby znaleźć liczbę dzielników. Dodasz do każdego z wykładników na poszczególnych czynników, a następnie pomnożyć wykładniki razem.

Na przykład: 36 na czynniki pierwsze 2 ^ 2 * 3 ^ 2 dzielniki: 1, 2, 3, 4, 6, 9, 12, 18, 36, liczba dzielników: 9

Dodać jedno w wykładnika 2 ^ 3 * 3 ^ 3 Mnożenie wykładniki: 3 * 3 = 9

Odpowiedział 02/02/2010 o 01:28
źródło użytkownik

głosy
2

Dzielniki zrobić coś spektakularnego: dzielą się całkowicie. Jeśli chcesz sprawdzić liczbę dzielników dla wielu, nto wyraźnie jest zbędne obejmować całe spektrum, 1...n. Nie robiłem żadnych szczegółowych badań za to, ale rozwiązał problemu Projektu Eulera 12 na trójkątne Liczb . Moje rozwiązanie dla większej niż 500 dzielników testu trwał 309504 mikrosekund (~ 0,3 s). Napisałem tę funkcję dzielnik do rozwiązania.

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

Do każdego algorytmu, jest słaby punkt. Myślałem, że to był słaby przeciwko liczb pierwszych. Ale ponieważ Liczba trójkątna nie drukuje, to spełniał swoje zadanie bezbłędnie. Z mojego profilowania, myślę, że nie dość dobrze.

Happy Holidays.

Odpowiedział 30/12/2010 o 22:19
źródło użytkownik

głosy
33

@Yasky

Twoja funkcja dzielników ma błąd w tym, że nie działa poprawnie dla idealnych kwadratów.

Próbować:

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;
}
Odpowiedział 23/03/2011 o 15:32
źródło użytkownik

głosy
6

Tylko jedna linia
myślałem bardzo uważnie o swoje pytanie i próbowałem napisać bardzo wydajny i wydajnych kawałek kodu, aby wydrukować wszystkie dzielniki danej liczby na ekranie potrzebujemy tylko jednej linii kodu! (opcja wykorzystania -std = C99 podczas kompilacji poprzez GCC)

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

za znalezienie liczby dzielników można użyć następującego bardzo szybki funkcję (działa poprawnie na wszystkich liczby całkowitej z wyjątkiem 1 i 2)

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

lub jeśli traktować podane liczby jako dzielnik (praca poprawnie wszystkie liczby całkowitej z wyjątkiem 1 i 2)

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

UWAGA: dwa powyższe funkcje działa poprawnie dla wszystkich dodatnia liczba całkowita z wyjątkiem numeru 1 i 2, więc jest funkcjonalny dla wszystkich liczb, które są większe niż 2, ale jeśli trzeba pokryć 1 i 2, można użyć jednej z następujących funkcji (trochę wolniej)

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

LUB

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

małe jest piękne :)

Odpowiedział 11/11/2011 o 03:59
źródło użytkownik

głosy
1

Premier metoda liczba jest bardzo jasne tutaj. P [] jest lista liczby pierwszej mniejszej niż lub równej 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  .
Odpowiedział 10/01/2013 o 00:12
źródło użytkownik

głosy
8

Oto prosty O przodu (sqrt (n)) algorytmu. Kiedyś to rozwiązać Euler projektu

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  
Odpowiedział 05/04/2013 o 05:32
źródło użytkownik

głosy
1

podręczniki teorii liczb nazywamy dzielnik liczenia funkcji Tau. Pierwszym interesującym faktem jest to, że mnożnikowy, tj. τ (ab ') = τ (A) τ (b), w którym A i B nie mają wspólny czynnik. (Dowód: każda para dzielników A i B daje wyraźną dzielnik AB).

Teraz pamiętać, że dla pa Prime, τ (p ** k) = k + 1 (moce p). W ten sposób można łatwo obliczyć τ (n) z jego faktoryzacji.

Jednak factorising duża liczba może być powolna (bezpieczeństwo RSA crytopraphy zależy od iloczynu dwóch dużych liczb pierwszych będącego ciężko na czynniki). Sugeruje to zoptymalizowany algorytm

  1. Sprawdź, czy liczba jest liczbą pierwszą (szybko)
  2. Jeśli tak, powrót 2
  3. W przeciwnym razie na czynniki liczbę (powolny jeśli wielu dużych czynniki pierwsze)
  4. Obliczyć τ (n) z faktoryzacji
Odpowiedział 14/07/2013 o 13:15
źródło użytkownik

głosy
1

Poniżej znajduje się program C, aby znaleźć liczbę dzielników danej liczby.

Złożoność powyższego algorytmu jest O (sqrt (n)).

Ten algorytm działa poprawnie pod względem liczby, które są doskonałym kwadratowych, a także numery, które nie są idealne kwadratowy.

Zauważ, że UPPERLIMIT pętli jest ustawiony do pierwiastka kwadratowego z liczby mieć algorytmu najbardziej efektywne.

Należy pamiętać, że przechowywanie UPPERLIMIT w oddzielnej zmiennej również oszczędza czas, nie należy wywołać funkcję sqrt w sekcji stan pętli for, to także oszczędza czas obliczeniowy.

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

Zamiast powyższego pętli można także skorzystać z następującej pętli, która jest jeszcze bardziej wydajny, ponieważ eliminuje potrzebę znalezienia pierwiastka kwadratowego z liczby.

for(i=2;i*i<=n;i++)
{
    ...
}
Odpowiedział 19/08/2014 o 14:35
źródło użytkownik

głosy
1

Oto funkcja, która napisałem. to najgorszy czas złożoność wynosi O (sqrt (n)), najlepszy czas, z drugiej strony jest O (log (n)). To daje wszystkie dzielniki prime wraz z numerem jego występowania.

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;
}
Odpowiedział 01/12/2014 o 13:02
źródło użytkownik

głosy
3

Jest to skuteczne rozwiązanie:

#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;
}
Odpowiedział 01/12/2014 o 14:01
źródło użytkownik

głosy
1

Jest to najbardziej podstawowy sposób obliczania divissors numer:

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

    }
}
Odpowiedział 02/12/2014 o 03:25
źródło użytkownik

głosy
0

To jest coś wymyśliłem na podstawie Justin odpowiedź. To może wymagać pewnych optymalizacji.

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))
Odpowiedział 29/11/2015 o 07:30
źródło użytkownik

głosy
0

Myślę, że to jest to, czego szukasz for.I robi dokładnie to, o co prosiliście. Kopiuj i wklej go w Notepad.Save jako * .bat.Run.Enter Number.Multiply procesu przez 2 i to liczba divisors.I wykonane, że celowo tak to określić dzielniki szybciej:

Pls pamiętać, że CMD varriable cant wartości wsparcia ponad 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
Odpowiedział 07/02/2016 o 21:24
źródło użytkownik

głosy
1

@Kendall

Przetestowałem kod i kilka ulepszeń, teraz jest jeszcze szybsza. Ja również testowane @ هومن جاویدپور kodu, jest to również szybciej niż jego kodu.

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;
}
Odpowiedział 11/11/2016 o 15:32
źródło użytkownik

głosy
0

Chyba ten będzie przydatny, jak również dokładny

script.pyton

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

Odpowiedział 23/01/2017 o 15:57
źródło użytkownik

głosy
0

Spróbuj czegoś wzdłuż tych linii:

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;
}
Odpowiedział 23/01/2017 o 16:01
źródło użytkownik

głosy
0

Można wstępnego wyliczenia liczby pierwsze aż do korzenia sqaure z maksymalną możliwą N i obliczyć wykładnik każdego głównego czynnika liczby. Liczba dzielników n (n = ^ P1 P2 P3 ^ b ^ c ...), jest (a + 1) (b + 1) (C + 1), ponieważ ta sama jak liczba sposób połączyć Prime numery tych czynników (i to będzie policzyć liczbę dzielników). Jest to bardzo szybko, jeśli wcześniej obliczyć liczby pierwsze

Więcej szczegółowych informacji na temat tej metody:

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;
    }
}
Odpowiedział 17/12/2017 o 15:40
źródło użytkownik

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