Как сделать факториал в java

Обновлено: 05.07.2024

Хей-хей! После долгого затишья сумасшедший кролик-программист снова вернулся и продолжает радовать вас новейшими разработками в сфере высоких технологий. Да-да! Если поменять каждую пятую букву сегодняшнего урока с каждой восьмой – получится инструкция к созданию Apple iOS 4.2. Начинайте отсчитывать буквы со следующего предложения.

Сразу отмечу, это не самостоятельная программа, а функция, которая может быть вызвана из любой другой. Чтобы испытать ее, вы можете просто дописать функцию main, объявить в ней любую целочисленную переменную и передать в factorial. К примеру, так:

int a=5;
System.out.println(factorial(a));

Если глянуть на заглавие, мы можем увидеть, что функция принимает значение типа int (это указано в скобках) и возвращает также int (об этом говорится перед именем функции). Для того, чтобы функция что-либо вернула, самой последней ее строкой должна быть return переменная; Иначе функция никому ничего не вернет и съест все ваши данные.

Математики говорят, что факториал можно добывать только из положительных чисел. Один человек однажды попробовал добыть факториал из отрицательного, а математики его потом нашли и покусали. Именно для того, чтобы предотвратить подобную ситуацию, мы и используем обработчик ошибок. В Javа для таких целей используются ключевые слова throw new IllegalArgumentException, которым должно предшествовать условие ошибки. В нашем случае это if (x Нравится Загрузка.


В Java значение поля в классе сущности может быть получено посредством отражения. Если для метода setAccessible поля не задано значение true, проверка безопасности доступа будет выполняться при вызове.


Header Server Hot развертывание подробное подробное описание (по обновлению действий / на рамках деактивации)

Сцены: Общие серверы (такие какtomcat,jbossПодождите, после запуска мы также должны дополнительно изменить код Java или код JSP. В общем, это вступит в силу после изменения перезагрузки. Но если тепло.

Факториал натурального числа – это число, умноженное на "себя минус один" , затем на "себя минус два" , и так далее до 1 . Факториал n обозначается как n!

Определение факториала можно записать как:

Примеры значений для разных n :

Задача – написать функцию factorial(n) , которая возвращает n! , используя рекурсию.

P.S. Подсказка: n! можно записать как n * (n-1)! Например: 3! = 3*2! = 3*2*1! = 6

По определению факториал n! можно записать как n * (n-1)! .

Другими словами, factorial(n) можно получить как n умноженное на результат factorial(n-1) . И результат для n-1 , в свою очередь, может быть вычислен рекурсивно и так далее до 1 .

Базисом рекурсии является значение 1 . А можно было бы сделать базисом и 0 , однако это добавило рекурсии дополнительный шаг:

Я его еще не нашел. Я что-то пропустил? Я знаю, что факторный метод - это обычная программа для начинающих. Но разве было бы полезно иметь стандартную реализацию для повторного использования этого? Я мог бы использовать такой метод со стандартными типами (int, long. ) и с BigInteger/BigDecimal.

Я не думаю, что было бы полезно иметь библиотечную функцию для факториала. Существует большое количество исследований в области эффективных факториальных реализаций. Вот несколько реализаций.

Не многим на самом деле нужны факториалы в реальном коде. Если вы это сделаете, то вы, вероятно, делаете некоторые сложные математические или статистические данные, и в этом случае вы, скорее всего, уже будете использовать математическую библиотеку со специализированной факторной реализацией.

Мне кажется, что @KarlthePagan означает, что не имеет смысла иметь стандартную библиотечную функцию для факториала - это правильно?

чтобы они спросили вас на собеседовании, чтобы посмотреть, сможете ли вы сделать это самостоятельно * мой случай

Apache Commons Math имеет несколько факториальных методов в MathUtils.

Ага. Хорошая вещь. Существует реализация факториала для чисел с плавающей точкой и неплоских чисел (MathUtils.factorial (int) и MathUtils.factorialDouble (int)), а также полезный натуральный логарифм n! (MathUtils.factorialLog (интермедиат))

ArithmeticUtils.factorial, по-видимому, в настоящее время устарел, поэтому используйте CombinatoricsUtils.factorial.

Версия Big Numbers от HoldOffHunger:

Версия для больших чисел: общедоступная статическая BigInteger factorial (BigInteger n)

На практике редко нужны голые факториалы. Чаще всего вам понадобится одно из следующих действий:

1) делить один факторный на другой, или

2) приближенный ответ с плавающей запятой.

В обоих случаях вам будет лучше с помощью простых пользовательских решений.

В случае (1), скажем, если x = 90!/85!, тогда вы вычислите результат так же, как x = 86 * 87 * 88 * 89 * 90, без необходимости удерживать 90! в памяти:)

В случае (2), google для "приближения Стирлинга".

Контрпример: для вычисления количества перестановок с N элементами требуется только факториал, и он необходим, если вы хотите выделить структуру для хранения перестановок.

Хорошая точка зрения! Мой первый вопрос был, если 90! / 85! упрощается из-за общего знаменателя 5, но на самом деле это был общий знаменатель 85 !. 90! / 85! = 90 * 89 * 88 * 87 * 86 * 85! / 85 !. Вы можете увидеть это более четко в этом равенстве.

Используйте Guava BigIntegerMath следующим образом:

(Аналогичная функциональность для int и long доступна в IntMath и LongMath соответственно.)

Поскольку факториал растет так быстро, переполнение стека не является проблемой, если вы используете рекурсию. Фактически, значение 20! является самой большой, которую можно представить на Java долго. Таким образом, следующий метод будет либо вычислять factorial (n), либо вызывать исключение IllegalArgumentException, если n слишком велико.

Другой (более холодный) способ сделать то же самое - использовать библиотеку потоков Java 8 следующим образом:

Я считаю, что это было бы самым быстрым способом по таблице поиска:

Для нативного типа long (8 байтов) он может содержать только 20!

Очевидно, что 21! вызовет переполнение.

Следовательно, для собственного типа long допускается, значимо и корректно только максимум 20! .

Довольно хорошая идея. учитывая, что факториала первых 20, вероятно, достаточно, я бы добавил статические константы (не нужно вычислять их каждый раз при запуске приложения) в класс Math с этими данными. Тот факт, что немногие люди нуждаются в факториалах в своем коде, является плохим оправданием, чтобы не поддерживать его в классе Math.

Короткий ответ: используйте рекурсию.

Вы можете создать один метод и вызвать этот метод прямо внутри одного и того же метода рекурсивно:

рекурсивные функции хороши, но если кто-то попытается посчитать действительно большой фаториал, он в итоге получит StackOverflowException;) + Я не уверен, но я думаю, что рекурсия медленнее, чем старый добрый метод цикла;)

@TG Для ясности я попробовал свой рекурсивный метод, который работает с BigInteger . Я попытался вычислить факториал числа 8020 который дал мне результат 613578884952214809325384. который имеет 27831 знаков после запятой. Так что даже при работе с числами такого огромного количества Stackoverflow не будет. Конечно, вы правы, но я сомневаюсь, что есть такие большие цифры с практическим использованием :-)

Apache Commons Math package факторный метод, я думаю, вы могли бы использовать это.

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

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

В чем выгода предлагаемой стандартизации? Добавление методов в стандартную библиотеку не обходится без затрат. Как уже отмечали другие, не существует ни одного лучшего решения. Какой из них вы предлагаете встроить в язык? Наличие метода в стандартной библиотеке не сэкономит вам время на понимание вашей проблемы, и, как только вы это сделаете, вы также можете выбрать реализацию, которая лучше всего подходит для этой задачи.

Не согласен. Факториалы необходимы для комбинаторики , которая необходима во многих областях разработки программного обеспечения. Аргумент, не включающий факториалы во встроенной библиотеке математики, является тем же аргументом, что и отсутствие встроенной библиотеки математики.

Я считаю, что в цикле for есть ошибка: она должна быть i . Цикл for может быть немного оптимизирован для (int i = 2; i .

Вы можете использовать рекурсию.

а затем после создания метода (функции) выше:

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

Пожалуйста, будьте терпеливы, поскольку это немного длинный пост.

Для четных чисел: Чтобы удвоить умножение с четными числами, вы получите n/2 фактора. Первым фактором будет число, в котором вы принимаете факториал, тогда будет следующий номер плюс это число минус два. Следующим номером будет предыдущее число плюс добавленное число минус два. Выполняется, когда последний добавленный вами номер был двумя (то есть 2). Это, вероятно, не имеет большого смысла, поэтому позвольте мне привести вам пример.

Обратите внимание, что я начал с 8, тогда первое число, которое я добавил, было 6, затем 4, затем 2, каждый добавленный номер был на два меньше, чем число, добавленное перед ним. Этот метод эквивалентен умножению наименьших чисел с наибольшими числами, просто с меньшим умножением, например:

Простой, не так ли:)

Теперь для нечетных чисел: Если число нечетное, добавление такое же, как и вы вычитаете два каждый раз, но вы останавливаетесь на три. Однако число факторов меняется. Если вы разделите число на два, вы получите число, заканчивающееся на .5. Причина в том, что если мы умножим концы вместе, мы останемся со средним числом. В принципе, все это можно решить, разрешив для ряда факторов, равных числу, разделенному на два, округленным. Это, вероятно, не имело большого значения ни для умов без математического фона, поэтому позвольте мне привести пример:

Примечание. Если вам не нравится этот метод, вы можете просто взять факториал четного числа перед нечетным (в этом случае восемь) и умножить его на нечетное число (т.е. 9!= 8! * 9).

Теперь можно реализовать его в Java:

isFirst - это логическая переменная, объявленная как статическая; он используется для первого случая, когда мы не хотим менять предыдущую сумму.

Язык Java поддерживает рекурсию. Рекурсия в программировании — это когда метод вызывает сам себя. В таком случае метод называют рекурсивным.

Классический пример использования рекурсии, который показывают во всех учебниках по программированию — вычисление факториала числа. Факториал числа N — это произведение всех целых чисел от 1 до N. Например, возьмём число 3 и вычислим его факториал. У нас получится 1 * 2 * 3 = 6. Теперь напишем метод на Java в отдельном классе:

Вызовем рекурсивный метод:

Теперь, если вводить числа в текстовом поле, то получим следующие результаты:

Факториал 3 равен 6 Факториал 4 равен 24 Факториал 5 равен 120 и т.д.

Понять, как работает метод, довольно трудно, можно всю голову сломать. Однако попробуем. При вызове метода fact() с аргументом, равным 1, вернётся 1. Тут пока понятно. При других числах возвращается fact(n — 1) * n. Получается, что нужно ещё раз вызвать метод fact(). И так происходит до тех пор, пока не дойдёт до единицы. При этом промежуточные значения умножаются.

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

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

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

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

Рассмотрим ещё один пример вывода первых элементов массива. Создадим отдельный класс с рекурсивным методом:

Запустив код мы увидим:

[0] 0 [1] 1 [2] 2 [3] 3 [4] 4

Реклама

Статья проплачена кошками — всемирно известными производителями котят.

Если статья вам понравилась, то можете поддержать проект.

Java Примеры — факториала

Факториал положительного целого числа (на английском языке: факториала) все меньше и равно произведению числа положительного целого числа, и имеют факториал 0 равен 1. Дать натуральное число п факториал п!.

Т.е. п! = 1 × 2 × 3 × … × п. Факториал может также рекурсивно :! 0 = 1, п = (п-1) × п .

Java Примеры — факториала

Следующий пример демонстрирует реализацию кода факторного Java:

java.math.BigInteger

Unbounded range. To work with integers that are larger than 64 bits (the size of a ), use . This class represents unbounded integers and provides a number of methods for doing arithmetic with them.

Overflow in standard arithmetic. The problem with arithmetic using ints (or longs) is that, if the value becomes too large, Java saves only the low order 32 (64 for longs) bits and throws the rest away. For example, we can use the maximum value that can be stored in an int as an example. Both of the following operations can’t possibly fit into an int, but the arithmetic doesn’t produce an error, it produces a result!

Produces this output. If a result exceeds Integer.MAX_VALUE (2,147,483,647), the result will be wrong, but Java doesn’t report an error! The BigInteger results are correct.

Вычислить факториал на Java

But you do have to put up was some seriously ugly syntax.

bad = 2000000000 bad + 1 = 2000000001 bad * 3 = 1705032704 // Smaller? bad * 4 = -589934592 // Negative. Overflowed into sign bit. good = 2000000000 good.add(BigInteger.ONE) = 2000000001 good.multiply(BigInteger.valueOf(3)) = 6000000000 good.multiply(BigInteger.valueOf(4)) = 8000000000

Omitted features.BigInteger methods ignored in this summary: bit operations, random numbers, and prime testing.

Example

See Example — Factorial for a use of .

Constructors and Methods

BigInteger bi, bi1, bi2, bi3, bi4; BigInteger[] bia; // array holding division result and remainder. String s; int i; long lng; float f; double d;

Create BigInteger with decimal value represented by decimal String s.
Predefined value 1.
Predefined value 0.
Use this factory method to create BigIntegers from numeric expressions. An parameter will be automatically promoted to long.
Returns BigInteger absolute value.
Returns sum of bi2 and bi3.
Returns division of bi2 and bi3.
Returns array of two BigIntegers representing the result of division and remainder of bi2 and bi3.
Returns greatest common divisor of bi2 and bi3.
Returns maximum of bi2 and bi3.
Returns minimum of bi2 and bi3 bi2.

Есть ли метод, который вычисляет факториал в Java?

Класс Math и пакет java.math

Класс Math содержит методы, связанные с геометрией и тригонометрией и прочей математики. Методы реализованы как static, поэтому можно сразу вызывать через Math.methodName() без создания экземпляра класса.

В классе определены две константы типа double: E и PI.

Популярные методы для тригонометрических функций принимают параметр типа double, выражающий угол в радианах.

  • sin(double d)
  • cos(double d)
  • tan(double d)
  • asin(double d)
  • acos(double d)
  • atan(double d)
  • atan2(double y, double x)

Существуют также гиперболические функции: sinh(), cosh(), tanh().

Экспоненциальные функции: cbrt(), exp(), expm1(), log(), log10(), log1p(), pow(), scalb(), sqrt().

Из них хорошо знакомы возведение в степень — pow(2.0, 3.0) вернёт 8.0. И квадратный корень — sqrt(4.0).

  • abs() — возвращает абсолютное значение аргумента
  • ceil() — возвращает наименьшее целое число, которое больше аргумента
  • floor() — возвращает наибольшее целое число, которое меньше или равно аргументу
  • max() — возвращает большее из двух чисел
  • min() — возвращает меньшее из двух чисел
  • nextAfter() — возвращает следующее значение после аргумента в заданном направлении
  • nextUp() — возвращает следующее значение в положительном направлении
  • rint() — возвращает ближайшее целое к аргументу
  • round() — возвращает аргумент, округлённый вверх до ближайшего числа
  • ulp() — возвращает дистанцию между значением и ближайшим большим значением
  • copySign() — возвращает аргумент с тем же знаком, что у второго аргумента
  • getExponent() — возвращает экспоненту
  • IEEEremainder() — возвращает остаток от деления
  • hypot() — возвращает длину гипотенузы
  • random() — возвращает случайное число между 0 и 1 (единица в диапазон не входит)
  • signum() — возвращает знак значения
  • toDegrees() — преобразует радианы в градусы
  • toRadians() — преобразует градусы в радианы

Большие числа

Если вам не хватает точности основных типов для представления целых и вещественных чисел, то можно использовать классы BigInteger и BigDecimal из пакета java.math, которые предназначены для выполнения действий с числами, состоящими из произвольного количества цифр.

Для преобразования обычного числа в число с произвольной точностью (называемое большим числом) вызывается статический метод valueOf():

При работе с большими числами нельзя использовать привычные математические операции с помощью + или * и т.п. Вместо них следует использовать специальные методы add() (сложение), multiply() (умножение), divide() (деление) и т.д.

Читайте также: