СЦБИСТ - сайт железнодорожников №1

СЦБИСТ - сайт железнодорожников №1 (https://scbist.com/)
-   Java (https://scbist.com/java/)
-   -   Функция вычисления факториала node.js (https://scbist.com/java/50244-funkciya-vychisleniya-faktoriala-node-javascript.html)

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

Admin 03.07.2018 10:40

Функция вычисления факториала 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).


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

Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot


Яндекс.Метрика