Учитывая последовательность чисел a [i] для i = 0 до N-1, я пытаюсь вычислить следующую сумму:
a[0] * a[1] * a[2] +
a[1] * a[2] * a[3] +
a[2] * a[3] * a[4] +
...
a[N-4] * a[N-3] * a[N-2] +
a[N-3] * a[N-2] * a[N-1]
Я хотел бы сделать размер G изумноженная группа (в приведенном выше примере 3) переменный параметр.Тогда результат может быть наивно получен с использованием простого алгоритма O (N * G), который может быть записан в псевдокоде так:
sum = 0
for i from 0 to (N-G-1):
group_contribution = 1
for j from 0 to (G-1):
group_contribution *= a[i+j]
sum += group_contribution
Однако для больших G очевидно, что этот алгоритм ужаснонеэффективно, особенно если предположить, что числа последовательности a [i] заранее не известны и требуют дорогостоящих вычислений во время выполнения.
По этой причине я рассмотрел использование следующего алгоритма сложности O (N + G), который повторяет значения последовательности a [i] путем вычисления скользящего произведения:
sum = 0
rolling_product = 1
for i from 0 to (G-1):
rolling_product *= a[i]
sum += rolling_product
for i from G to (N-1):
rolling_product /= a[i-G]
rolling_product *= a[i]
sum += rolling_product
Однако меня беспокоит численная стабильность деления в стандартном представлении с плавающей точкой.
Мне было бы интересно узнать, существует ли стабильный, более быстрый способ вычисления этой суммы.Для меня это похоже на простую числовую задачу, но в настоящее время я не знаю, как это сделать эффективно.
Спасибо за любые идеи!