Гид по технологиям

Как найти произведение всех элементов массива

4 min read Algorithms Обновлено 15 Dec 2025
Произведение элементов массива — итеративно и рекурсивно
Произведение элементов массива — итеративно и рекурсивно

Экран ноутбука с кодом на C++, Python, JavaScript и C

Массив — это набор элементов, расположенных в смежных ячейках памяти. Это одна из самых распространённых структур данных. Часто требуется выполнять базовые операции с массивом: вставка, удаление, обход, сумма или произведение всех элементов.

В этой статье показаны два подхода к вычислению произведения всех элементов массива: итеративный (циклы) и рекурсивный. Приведены примеры на C++, Python, JavaScript и C, а также рекомендации по обработке краевых случаев.

Задача

Дан массив arr. Нужно вычислить произведение всех элементов массива и вывести результат. Реализуйте решение циклом и рекурсией.

Пример 1: arr = [1, 2, 3, 4, 5, 6, 7, 8]

Произведение = 1 2 3 4 5 6 7 * 8 = 40320

Вывод: 40320

Пример 2: arr = [1, 1, 1, 1, 1, 1]

Произведение = 1

Вывод: 1

Итеративный подход

Идея простая: завести переменную result и последовательно умножать в неё элементы массива.

Шаги:

  1. Инициализируйте result значением 1.
  2. Пройдитесь по всем элементам массива циклом.
  3. Для каждого элемента умножьте result на этот элемент.
  4. Верните result.

Временная сложность: O(n). Потребление памяти: O(1).

C++ — итеративно

// C++ program to find the product of the array elements
#include 
using namespace std;

long long findProduct(int arr[], int size)
{
    long long result = 1;
    for (int i = 0; i < size; i++)
    {
        result = result * arr[i];
    }
    return result;
}

void printArrayElements(int arr[], int size)
{
    for (int i = 0; i < size; i++)
    {
        cout << arr[i] << " ";
    }
    cout << endl;
}

int main()
{
    int arr1[] = {1, 2, 3, 4, 5, 6, 7, 8};
    int size1 = sizeof(arr1) / sizeof(arr1[0]);
    cout << "Array 1:" << endl;
    printArrayElements(arr1, size1);
    cout << "Product of the array elements: " << findProduct(arr1, size1) << endl;

    int arr2[] = {1, 1, 1, 1, 1, 1};
    int size2 = sizeof(arr2) / sizeof(arr2[0]);
    cout << "Array 2:" << endl;
    printArrayElements(arr2, size2);
    cout << "Product of the array elements: " << findProduct(arr2, size2) << endl;

    return 0;
}

Вывод программы:

Array 1:
1 2 3 4 5 6 7 8
Product of the array elements: 40320
Array 2:
1 1 1 1 1 1
Product of the array elements: 1

Python — итеративно

# Python program to find product of the list elements

def findProduct(arr):
    result = 1
    for val in arr:
        result = result * val
    return result


def printListElements(arr):
    for val in arr:
        print(val, end=" ")
    print()

arr1 = [1, 2, 3, 4, 5, 6, 7, 8]
print("Array 1:")
printListElements(arr1)
print("Product of the array elements:", findProduct(arr1))

arr2 = [1, 1, 1, 1, 1, 1]
print("Array 2:")
printListElements(arr2)
print("Product of the array elements:", findProduct(arr2))

Вывод тот же, что и в C++.

JavaScript — итеративно

// JavaScript program to find the product of the array elements

function findProduct(arr) {
  let result = 1;
  for (let i = 0; i < arr.length; i++) {
    result = result * arr[i];
  }
  return result;
}

function printArrayElements(arr) {
  let out = '';
  for (let i = 0; i < arr.length; i++) {
    out += arr[i] + ' ';
  }
  console.log(out);
}

var arr1 = [1, 2, 3, 4, 5, 6, 7, 8];
console.log('Array 1:');
printArrayElements(arr1);
console.log('Product of the array elements: ' + findProduct(arr1));

var arr2 = [1, 1, 1, 1, 1, 1];
console.log('Array 2:');
printArrayElements(arr2);
console.log('Product of the array elements: ' + findProduct(arr2));

C — итеративно

// C program to find the product of the array elements
#include 

long long findProduct(int arr[], int size)
{
    long long result = 1;
    for (int i = 0; i < size; i++)
    {
        result = result * arr[i];
    }
    return result;
}

void printArrayElements(int arr[], int size)
{
    for (int i = 0; i < size; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main()
{
    int arr1[] = {1, 2, 3, 4, 5, 6, 7, 8};
    int size1 = sizeof(arr1) / sizeof(arr1[0]);
    printf("Array 1:\n");
    printArrayElements(arr1, size1);
    printf("Product of the array elements: %lld\n", findProduct(arr1, size1));

    int arr2[] = {1, 1, 1, 1, 1, 1};
    int size2 = sizeof(arr2) / sizeof(arr2[0]);
    printf("Array 2:\n");
    printArrayElements(arr2, size2);
    printf("Product of the array elements: %lld\n", findProduct(arr2, size2));

    return 0;
}

Рекурсивный подход

Рекурсия вычисляет произведение, умножая последний элемент на произведение префикса массива.

Псевдокод:

function findProduct(arr, n):
    if n == 0:
        return arr[0]
    else:
        return arr[n] * findProduct(arr, n - 1)

При вызове передаём индекс последнего элемента: findProduct(arr, size - 1).

Временная сложность рекурсивного решения тоже O(n), но глубина рекурсии равна n, что может привести к переполнению стека для очень больших массивов.

C++ — рекурсивно

// C++ program to find the product of the array elements using recursion
#include 
using namespace std;

long long findProduct(int arr[], int n)
{
    if (n == 0)
    {
        return arr[0];
    }
    else
    {
        return (long long)arr[n] * findProduct(arr, n - 1);
    }
}

void printArrayElements(int arr[], int size)
{
    for (int i = 0; i < size; i++)
    {
        cout << arr[i] << " ";
    }
    cout << endl;
}

int main()
{
    int arr1[] = {1, 2, 3, 4, 5, 6, 7, 8};
    int size1 = sizeof(arr1) / sizeof(arr1[0]);
    cout << "Array 1:" << endl;
    printArrayElements(arr1, size1);
    cout << "Product of the array elements: " << findProduct(arr1, size1 - 1) << endl;

    int arr2[] = {1, 1, 1, 1, 1, 1};
    int size2 = sizeof(arr2) / sizeof(arr2[0]);
    cout << "Array 2:" << endl;
    printArrayElements(arr2, size2);
    cout << "Product of the array elements: " << findProduct(arr2, size2 - 1) << endl;
    return 0;
}

Python — рекурсивно

# Python program to find the product of the list elements using recursion

def findProduct(arr, n):
    if n == 0:
        return arr[0]
    else:
        return arr[n] * findProduct(arr, n - 1)

arr1 = [1, 2, 3, 4, 5, 6, 7, 8]
print("Array 1:")
print(*arr1)
print("Product of the array elements:", findProduct(arr1, len(arr1) - 1))

arr2 = [1, 1, 1, 1, 1, 1]
print("Array 2:")
print(*arr2)
print("Product of the array elements:", findProduct(arr2, len(arr2) - 1))

JavaScript — рекурсивно

// JavaScript program to find the product of the array elements using recursion

function findProduct(arr, n) {
  if (n === 0) {
    return arr[0];
  } else {
    return arr[n] * findProduct(arr, n - 1);
  }
}

var arr1 = [1, 2, 3, 4, 5, 6, 7, 8];
console.log('Array 1:');
console.log(arr1.join(' '));
console.log('Product of the array elements: ' + findProduct(arr1, arr1.length - 1));

var arr2 = [1, 1, 1, 1, 1, 1];
console.log('Array 2:');
console.log(arr2.join(' '));
console.log('Product of the array elements: ' + findProduct(arr2, arr2.length - 1));

C — рекурсивно

// C program to find the product of the array elements using recursion
#include 

long long findProduct(int arr[], int n)
{
    if (n == 0)
    {
        return arr[0];
    }
    else
    {
        return (long long)arr[n] * findProduct(arr, n - 1);
    }
}

void printArrayElements(int arr[], int size)
{
    for (int i = 0; i < size; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main()
{
    int arr1[] = {1, 2, 3, 4, 5, 6, 7, 8};
    int size1 = sizeof(arr1) / sizeof(arr1[0]);
    printf("Array 1:\n");
    printArrayElements(arr1, size1);
    printf("Product of the array elements: %lld\n", findProduct(arr1, size1 - 1));

    int arr2[] = {1, 1, 1, 1, 1, 1};
    int size2 = sizeof(arr2) / sizeof(arr2[0]);
    printf("Array 2:\n");
    printArrayElements(arr2, size2);
    printf("Product of the array elements: %lld\n", findProduct(arr2, size2 - 1));

    return 0;
}

Когда подходы не сработают или требуют доработки

  • Наличие нуля в массиве даёт ответ 0. Если нужно пропустить нули — учитывайте это в логике.
  • Переполнение числового типа: для int/long при больших значениях результат может превысить диапазон. Используйте 64‑битные типы или библиотеки больших целых (BigInt в JS, boost::multiprecision в C++).
  • Рекурсия опасна для очень больших массивов — возможен stack overflow. В таких случаях используйте итерацию.

Альтернативные подходы

  • Суммирование логарифмов: для очень больших произведений можно суммировать ln(x) и затем экспоненцировать; это даёт приближённый результат и удобно для сравнения масштабов.
  • Работа в произвольной точности: bigint или специальные библиотеки для точных целых.

Практические правила и эвристики

  • Если массив длинный (>10^4) и платформа ограничена по стеку — используйте итерацию.
  • Если нужно сравнивать произведения (без вычисления самого произведения), сравнивайте суммы логов.
  • Всегда проверяйте наличие нулей и отрицательных чисел (знак результата зависит от количества отрицательных элементов).

Набор тестов (критические кейсы)

  1. Пустой массив — определите ожидаемое поведение (обычно возвращают 1 или сообщают ошибку).
  2. Массив с одним элементом.
  3. Массив, содержащий ноль.
  4. Массив с отрицательными числами (чётное/нечётное количество отрицательных).
  5. Очень большой массив, приводящий к переполнению стандартного типа.

Критерии приёмки

  • Функция корректно возвращает произведение для положительных, отрицательных и нулевых значений.
  • Для пустого массива поведение описано в документации.
  • Для больших значений предусмотрена обработка переполнения (либо предупреждение, либо использование bigint).
  • Решение проходит все перечисленные тесты.

Короткий глоссарий

  • Произведение: результат последовательного умножения элементов.
  • BigInt: тип данных для целых чисел произвольной длины.
  • Stack overflow: ошибка при переполнении стека вызовов в рекурсии.

Краткое резюме

  • Итерация и рекурсия оба дают O(n).
  • Итерация безопаснее при больших n, рекурсия короче по коду.
  • Следите за нулями и переполнением; при необходимости используйте BigInt или логарифмическую технику.

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

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство