Алгоритм для вычисления количества делителей данного числа

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
172
задан tshepang 7 June 2014 в 20:57
поделиться

12 ответов

Dmitriy прав, что Вы захотите, чтобы Решето Atkin генерировало главный список, но я не полагаю, что это заботится о целой проблеме. Теперь, когда у Вас есть список начал, необходимо будет видеть, сколько из тех начал действует как делитель (и как часто).

<забастовка> Вот некоторый Python для алгоритма Взгляд здесь и поиск "Предмета: математике - нужен алгоритм делителей". Просто считайте количество объектов в списке вместо того, чтобы возвратить их как бы то ни было.

Вот доктор Math , который объясняет, что точно это - Вы, должен сделать математически.

По существу это сводится к тому, если Ваш номер n:
n = a^x * b^y * c^z
(где a, b, и c являются главными делителями и x n, y, и z являются количеством раз, что делитель повторяется) тогда общий счет для всех делителей:
(x + 1) * (y + 1) * (z + 1).

Редактирование: BTW, для нахождения a, b, c, и т.д. Вы захотите сделать, какие суммы к жадному алгоритму, если я пойму это правильно. Запустите со своего самого большого главного делителя и умножьте его отдельно, пока дальнейшее умножение не превысило бы номер n. Тогда переместите в следующий самый низкий фактор и времена предыдущее главное ^ количество раз, это было умножено на текущее начало, и продолжайте умножаться началом, пока следующее не превысит n... и т.д. Отслеживают количество раз, Вы умножаете делители вместе и применяете те числа в формулу выше.

Не 100%, уверенных в моем описании алгоритма, но если это не он, это - что-то подобное.

78
ответ дан oers 23 November 2019 в 20:40
поделиться

Я не знаю наиболее эффективный метод, но я сделал бы следующее:

  • Составляют таблицу начал для нахождения всех начал меньше чем или равными квадратному корню числа (Лично, я использовал бы Решето Atkin)
  • количество все начала, меньше чем или равные квадратному корню числа, и умножьте это на два. Если квадратный корень числа является целым числом, то вычтите один из переменной количества.

Должен работать \o /

, Если Вам нужно, я могу кодировать что-то завтра в C для демонстрации.

-1
ответ дан SemiColon 23 November 2019 в 20:40
поделиться

Это не просто вопрос факторинга числа - определение всех факторов числа? Можно тогда решить, нужны ли Вам все комбинации одного или нескольких факторов.

Так, один возможный алгоритм был бы:

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
ответ дан Jonathan Leffler 23 November 2019 в 20:40
поделиться

Вы хотите Решето Atkin, описанного здесь: http://en.wikipedia.org/wiki/Sieve_of_Atkin

1
ответ дан SquareCog 23 November 2019 в 20:40
поделиться

Решето Atkin является оптимизированной версией решета Эратосфена, которое дает всем простым числам до данного целого числа. Необходимо быть в состоянии погуглить это для большего количества детали.

, Как только у Вас есть тот список, это - простой вопрос для деления числа на каждое начало, чтобы видеть, является ли это точный делитель (т.е. остаток является нулем).

основные шаги, вычисляющие делители для номера (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
ответ дан paxdiablo 23 November 2019 в 20:40
поделиться

Ответ на Ваш вопрос зависит значительно от размера целого числа. Методы для небольших чисел, например, меньше тогда 100 битов, и для чисел ~1000 битов (такой, как используется в криптографии) полностью отличаются.

9
ответ дан killmgood 23 November 2019 в 20:40
поделиться

Этот интересный вопрос намного более труден, чем это смотрит, и этому не ответили. Вопрос может быть включен в 2 совсем других вопроса.

1 данный N, найдите список L простых множителей N

2 данных L, вычислите количество уникальных комбинаций

Все ответы, которые я вижу, до сих пор относятся к № 1 и сбою, чтобы упомянуть, что это не послушно для огромного количества. Для умеренно размерного N, даже 64-разрядных чисел, это легко; для огромного N проблема факторинга может взять "навсегда". Шифрование с открытым ключом зависит от этого.

для Вопроса № 2 нужно больше обсуждения. Если L содержит только уникальные числа, это - простое вычисление с помощью формулы комбинации для выбора k объекты от n объектов. На самом деле необходимо суммировать результаты применения формулы при варьировании k от 1 до sizeof (L). Однако L будет обычно содержать несколько случаев нескольких начал. Например, L = {2,2,2,3,3,5} факторизация N = 360. Теперь эта проблема является довольно трудной!

Повторное заявление № 2, учитывая набор C содержащий k объекты, такие, что объект' дубликаты и объект b имеет b' дубликаты, и т.д. сколько уникальные комбинации 1 к k-1 объектам там? Например, {2}, {2,2}, {2,2,2}, {2,3}, {2,2,3,3} должен каждый произойти однажды и только однажды если L = {2,2,2,3,3,5}. Каждый такой уникальный поднабор является уникальным делителем N путем умножения объектов в поднаборе.

10
ответ дан dongilmore 23 November 2019 в 20:40
поделиться

Я не соглашаюсь, что решето Atkin является способом пойти, потому что могло легко занять больше времени регистрировать каждое число [1, n] для простоты чисел, чем это будет для сокращения количества подразделениями.

Вот некоторый код, который, хотя немного hackier, обычно намного быстрее:

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 для решения этой проблемы.

28
ответ дан Tyler 23 November 2019 в 20:40
поделиться

Существуют партия [еще 114] методы к факторингу, чем решето Atkin. Например, предположите, что мы хотим к фактору 5893. Хорошо его sqrt 76.76... Теперь мы попытаемся записать 5893 как продукт квадратов. Хорошо (77*77 - 5893) = 36, который равняется 6 в квадрате, таким образом, 5893 = 77*77 - 6*6 = (77 + 6) (77-6) = 83*71. Если бы это не работало, то мы посмотрели бы на то, был ли 78*78 - 5893 полным квадратом. И так далее. С этой техникой можно быстро протестировать на факторы около квадратного корня n намного быстрее, чем путем тестирования отдельных начал. При объединении этой техники для исключения больших начал с решетом у Вас будет намного лучший метод факторинга, чем с решетом одним.

И это - только одно из большого количества методов, которые были разработаны. Это - довольно простое. Вам потребовалось бы долгое время для изучения, скажем, достаточной теории чисел для понимания методов факторинга на основе эллиптических кривых. (Я знаю, что они существуют. Я не понимаю их.)

Поэтому, если Вы не имеете дело с маленькими целыми числами, я не попытался бы решить ту проблему сам. Вместо этого я попытался бы найти способ использовать что-то как библиотека PARI, которой уже реализовали высокоэффективное решение. С этим я могу учесть случайные 40 чисел цифры как 124321342332143213122323434312213424231341 приблизительно через.05 секунд. (Его факторизация, в случае, если Вы задались вопросом, 29*439*1321*157907*284749*33843676813*4857795469949. Я довольно уверен, что это не изображало это использование решета Atkin...)

47
ответ дан user11318 23 November 2019 в 20:40
поделиться

Прежде чем вы выберете решение, подумайте о том, что подход Sieve не может быть хорошим ответом в типичном случае.

Некоторое время назад возник главный вопрос, и я провел временную проверку. -для 32-битных целых чисел хотя бы определение того, было ли оно простым, было медленнее, чем грубая сила. Имеются два фактора:

1) Хотя человеку требуется время, чтобы выполнить деление, он очень быстро работает с компьютером - аналогично стоимости поиска ответа.

2) Если вы этого не сделаете. Имея простую таблицу, вы можете создать цикл, который будет полностью выполняться в кэше L1. Это делает его быстрее.

3
ответ дан 23 November 2019 в 20:40
поделиться

Вы можете попробовать вот это. Это немного взломано, но достаточно быстро.

def factors(n):
    for x in xrange(2,n):
        if n%x == 0:
            return (x,) + factors(n/x)
    return (n,1)
5
ответ дан 23 November 2019 в 20:40
поделиться

После первичной факторизации есть способ найти количество делителей. Добавьте по одному к каждому из экспонентов на каждый отдельный фактор и затем умножьте экспоненты вместе.

Например: 36 Основной Факторизация: 2^2*3^2 Разделители: 1, 2, 3, 4, 6, 9, 12, 18, 36 Количество Разделителей: 9

Добавьте по одному к каждому экспоненте 2^3*3^3 Умножь экспоненты: 3*3 = 9

5
ответ дан 23 November 2019 в 20:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: