СЦБИСТ - сайт железнодорожников №1
Вернуться   СЦБИСТ - сайт железнодорожников №1 > Техника > Программирование и системное администрирование > Java
Java Обсуждение вопросов по программированию на Java
Закладки ДневникиПоддержка Сообщество Комментарии к фото Сообщения за день
Ответить в этой теме   Перейти в раздел этой темы    
 
В мои закладки Подписка на тему по электронной почте Отправить другу по электронной почте Опции темы Поиск в этой теме
Старый 03.07.2018, 10:40   #1 (ссылка)
Crow indian
 
Аватар для Admin

Регистрация: 21.02.2009
Возраст: 41
Сообщений: 30,380
Поблагодарил: 398 раз(а)
Поблагодарили 6046 раз(а)
Фотоальбомы: 2624 фото
Записей в дневнике: 904
Репутация: 126146

Тема: Функция вычисления факториала node.js


В Node.js есть несколько способов реализации функции вычисления факториала. Рассмотрю все варианты — от простого до оптимизированного.

 
Содержание

1. Итеративный способ (рекомендуемый)


Самый эффективный и безопасный способ:

PHP код:
function factorialIterative(n) {
    if (
0) throw new Error('Факториал определён только для неотрицательных чисел');
    if (
=== || === 1) return 1;
    
    
let result 1;
    for (
let i 2<= ni++) {
        
result *= i;
    }
    return 
result;
}

// Использование
console.log(factorialIterative(5)); // 120
console.log(factorialIterative(10)); // 3628800 

2. Рекурсивный способ


Классический, но с ограничениями:
Ограничение: для больших n (> 10000) может вызвать переполнение стека.

PHP код:
function factorialRecursive(n) {
    if (
0) throw new Error('Факториал определён только для неотрицательных чисел');
    if (
=== || === 1) return 1;
    return 
factorialRecursive(1);
}

// Использование
console.log(factorialRecursive(5)); // 120 

3. Оптимизированный рекурсивный (хвостовая рекурсия)


PHP код:
function factorialTailRecursive(naccumulator 1) {
    if (
0) throw new Error('Факториал определён только для неотрицательных чисел');
    if (
=== || === 1) return accumulator;
    return 
factorialTailRecursive(1accumulator);
}

// Использование
console.log(factorialTailRecursive(5)); // 120 

4. С использованием BigInt (для очень больших чисел)


PHP код:
function factorialBigInt(n) {
    if (
0) throw new Error('Факториал определён только для неотрицательных чисел');
    if (
=== || === 1) return 1n;
    
    
let result 1n;
    for (
let i 2n<= ni++) {
        
result *= i;
    }
    return 
result;
}

// Использование
console.log(factorialBigInt(20)); // 2432902008176640000n
console.log(factorialBigInt(50).toString()); // Огромное число 

5. С мемоизацией (кэширование результатов)


PHP код:
const factorialMemo = (function() {
    const 
cache = { 011};
    
    return function 
factorial(n) {
        if (
0) throw new Error('Факториал определён только для неотрицательных чисел');
        if (
cache[n] !== undefined) return cache[n];
        
        
cache[n] = factorial(1);
        return 
cache[n];
    };
})();

// Использование
console.log(factorialMemo(5)); // 120 (вычисляется)
console.log(factorialMemo(5)); // 120 (берётся из кэша)
console.log(factorialMemo(6)); // 720 (использует кэшированный 5!) 

6. Асинхронная версия (для неблокирующих операций)


PHP код:
async function factorialAsync(n) {
    if (
0) throw new Error('Факториал определён только для неотрицательных чисел');
    if (
=== || === 1) return 1;
    
    
let result 1;
    for (
let i 2<= ni++) {
        
result *= i;
        
// Периодически уступаем управление для других операций
        
if (1000 === 0) {
            
await new Promise(resolve => setImmediate(resolve));
        }
    }
    return 
result;
}

// Использование
(async () => {
    
console.log(await factorialAsync(5)); // 120
})(); 

7. С обработкой ошибок и валидацией


PHP код:
function factorialSafe(n) {
    
// Проверка типа
    
if (!Number.isInteger(n)) {
        throw new 
TypeError('Аргумент должен быть целым числом');
    }
    
    
// Проверка на отрицательное значение
    
if (0) {
        throw new 
RangeError('Факториал определён только для неотрицательных чисел');
    }
    
    
// Проверка на слишком большое число
    
if (170) {
        throw new 
RangeError('Результат выходит за пределы Number.MAX_SAFE_INTEGER');
    }
    
    if (
=== || === 1) return 1;
    
    
let result 1;
    for (
let i 2<= ni++) {
        
result *= i;
    }
    return 
result;

Сравнение производительности


PHP код:
const 100;

console.time('Итеративный');
factorialIterative(n);
console.timeEnd('Итеративный');

console.time('Рекурсивный');
factorialRecursive(n);
console.timeEnd('Рекурсивный');

console.time('Мемоизация');
factorialMemo(n);
console.timeEnd('Мемоизация'); 

Рекомендации:


Для большинства случаев используйте итеративный способ — он быстрый и безопасный

Для больших чисел (> 170) используйте BigInt

Для многократных вычислений используйте мемоизацию

Для академических целей подойдёт рекурсивный способ

В production всегда добавляйте валидацию входных данных

Помните, что факториал быстро растёт: 20! ≈ 2.43e18, что уже превышает безопасный предел для Number в JavaScript (2^53 - 1).
Admin вне форума   Цитировать 14
Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Многократная авторизация: svk Admin Обсуждение форума 0 18.01.2016 05:55
Многократная авторизация: U-54 Admin Обсуждение форума 0 25.11.2015 19:38
Многократная авторизация: U-54 Admin Обсуждение форума 0 19.08.2015 17:21

Ответить в этой теме   Перейти в раздел этой темы   Translate to English


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.



Часовой пояс GMT +3, время: 06:10.

Яндекс.Метрика Справочник 
сцбист.ру сцбист.рф

СЦБИСТ (ранее назывался: Форум СЦБистов - Railway Automation Forum) - крупнейший сайт работников локомотивного хозяйства, движенцев, эсцебистов, путейцев, контактников, вагонников, связистов, проводников, работников ЦФТО, ИВЦ железных дорог, дистанций погрузочно-разгрузочных работ и других железнодорожников.
Связь с администрацией сайта: admin@scbist.com
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 
Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Powered by NuWiki v1.3 RC1 Copyright ©2006-2007, NuHit, LLC Перевод: zCarot