Нахождение LCM диапазона чисел

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

20
задан Community 23 May 2017 в 12:02
поделиться

7 ответов

Эта проблема интересна, потому что она не требует, чтобы Вы нашли LCM произвольного набора чисел, Вам дают последовательный диапазон. Можно использовать изменение Решето Эратосфена для нахождения ответа.

def RangeLCM(first, last):
    factors = range(first, last+1)
    for i in range(0, len(factors)):
        if factors[i] != 1:
            n = first + i
            for j in range(2*n, last+1, n):
                factors[j-first] = factors[j-first] / factors[i]
    return reduce(lambda a,b: a*b, factors, 1)

<час> Редактирование: недавний upvote заставил меня вновь исследовать этот ответ, которому более чем 3 года. Мое первое наблюдение состоит в том, что я записал бы это немного по-другому сегодня, с помощью enumerate, например. Несколько небольших изменений были необходимы для создания этого совместимым с Python 3.

, которым второе наблюдение состоит в том, что этот алгоритм только работает, если запуск диапазона равняется 2 или меньше, потому что это не пытается просеять общие множители ниже запуска диапазона. Например, RangeLCM (10, 12) возвращает 1320 вместо корректных 660.

третье наблюдение состоит в том, что никто не делал попытку ко времени этого ответа против никаких других ответов. Мой пищеварительный тракт сказал, что это улучшит по грубой силе решение LCM, поскольку диапазон стал больше. Тестирование доказало мой корректный пищеварительный тракт, по крайней мере, это однажды.

, Так как алгоритм не работает на произвольные диапазоны, я переписал его, чтобы предположить, что диапазон запускается в 1. Я удалил вызов к reduce в конце, поскольку было легче вычислить результат, поскольку факторы были сгенерированы. Я полагаю, что новая версия функции и более корректна и легче понять.

def RangeLCM2(last):
    factors = list(range(last+1))
    result = 1
    for n in range(last+1):
        if factors[n] > 1:
            result *= factors[n]
            for j in range(2*n, last+1, n):
                factors[j] //= factors[n]
    return result

Вот некоторые сравнения синхронизации с оригиналом и решением, предложенным Joe Bebel , который называют RangeEuclid в моих тестах.

>>> t=timeit.timeit
>>> t('RangeLCM.RangeLCM(1, 20)', 'import RangeLCM')
17.999292996735676
>>> t('RangeLCM.RangeEuclid(1, 20)', 'import RangeLCM')
11.199833288867922
>>> t('RangeLCM.RangeLCM2(20)', 'import RangeLCM')
14.256165588084514
>>> t('RangeLCM.RangeLCM(1, 100)', 'import RangeLCM')
93.34979585394194
>>> t('RangeLCM.RangeEuclid(1, 100)', 'import RangeLCM')
109.25695507389901
>>> t('RangeLCM.RangeLCM2(100)', 'import RangeLCM')
66.09684505991709

Для диапазона 1 - 20 данных в вопросе, алгоритм Euclid сбивает и мои старые и новые ответы. Для диапазона 1 - 100 Вы видите основанное на решете получение по запросу алгоритма вперед, особенно оптимизированная версия.

12
ответ дан 29 November 2019 в 23:09
поделиться

В том, чтобы подробно останавливаться на комментарии @Alexander я указал бы, что, если можно учесть числа к их началам, удалить дубликаты, затем умножение, у Вас будет свой ответ.

, Например, 1-5 имеют простые множители 2,3,2,2,5. Удалите дублированный '2' из факторного списка эти '4', и Вы имеете 2,2,3,5. Умножение их вместе уступает 60, который является Вашим ответом.

ссылка Вольфрама, предоставленная в предыдущем комментарии, , http://mathworld.wolfram.com/LeastCommonMultiple.html входит в намного более формальный подход, но короткая версия выше.

Аплодисменты.

-1
ответ дан 29 November 2019 в 23:09
поделиться

Алгоритм в Haskell. Это - язык, в котором я думаю в наше время для алгоритмических взглядов. Это могло бы казаться странным, сложным и непривлекательным - нравящийся Haskell!

primes :: (Integral a) => [a]
--implementation of primes is to be left for another day.

primeFactors :: (Integral a) => a -> [a]
primeFactors n = go n primes where
    go n ps@(p : pt) =
        if q < 1 then [] else
        if r == 0 then p : go q ps else
        go n pt
        where (q, r) = quotRem n p

multiFactors :: (Integral a) => a -> [(a, Int)]
multiFactors n = [ (head xs, length xs) | xs <- group $ primeFactors $ n ]

multiProduct :: (Integral a) => [(a, Int)] -> a
multiProduct xs = product $ map (uncurry (^)) $ xs

mergeFactorsPairwise [] bs = bs
mergeFactorsPairwise as [] = as
mergeFactorsPairwise a@((an, am) : _) b@((bn, bm) : _) =
    case compare an bn of
        LT -> (head a) : mergeFactorsPairwise (tail a) b
        GT -> (head b) : mergeFactorsPairwise a (tail b)
        EQ -> (an, max am bm) : mergeFactorsPairwise (tail a) (tail b)

wideLCM :: (Integral a) => [a] -> a
wideLCM nums = multiProduct $ foldl mergeFactorsPairwise [] $ map multiFactors $ nums
1
ответ дан 29 November 2019 в 23:09
поделиться

Острота в Haskell.

wideLCM = foldl lcm 1

Это - то, что я использовал для своей собственной Euler проблемы Проекта 5.

5
ответ дан 29 November 2019 в 23:09
поделиться

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

Вместо этого необходимо вычислить LCM единственной пары путем вычислений GCD с помощью алгоритма Euclid (который НЕ требует факторизации и на самом деле значительно быстрее):


def lcm(a,b):
    gcd, tmp = a,b
    while tmp != 0:
        gcd,tmp = tmp, gcd % tmp
    return a*b/gcd

затем можно найти общий LCM моим сокращением массива с помощью вышеупомянутого LCM () функция:


reduce(lcm, range(1,21))
19
ответ дан 29 November 2019 в 23:09
поделиться

LCM одного или нескольких чисел является продуктом всех отличных простых множителей во всех числах, каждом начале к питанию макс. из всех полномочий, к которым то начало появляется в числах, из которых каждый берет LCM.

Говорят 900 = 2^3 * 3^2 * 5^2, 26460 = 2^2 * 3^3 * 5^1 * 7^2. Макс. питание 2 равняется 3, макс. питание 3 равняется 3, макс. питание 5 равняется 1, макс. питание 7 равняется 2, и макс. питание любого более высокого начала 0. Таким образом, LCM: 264600 = 2^3 * 3^3 * 5^2 * 7^2.

2
ответ дан 29 November 2019 в 23:09
поделиться

Вот мой удар Python в нем:

#!/usr/bin/env python

from operator import mul

def factor(n):
    factors = {}
    i = 2 
    while i <= n and n != 1:
        while n % i == 0:
            try:
                factors[i] += 1
            except KeyError:
                factors[i] = 1
            n = n / i
        i += 1
    return factors

base = {}
for i in range(2, 2000):
    for f, n in factor(i).items():
        try:
            base[f] = max(base[f], n)
        except KeyError:
            base[f] = n

print reduce(mul, [f**n for f, n in base.items()], 1)

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

0
ответ дан 29 November 2019 в 23:09
поделиться
Другие вопросы по тегам:

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