В оригинальной версии этого ответа использован ASCII art.
Итак,
- ∑ i: 0..n i = n (n + 1) (½)
- ∑ i: 0..n i 2 =n (n + 1) (2n + 1) (⅙)
Отметим, что
- ∑ i: 0..n (x + i) 2
= ∑ i: 0 ... n x 2 + 2xi + i 2
= (n + 1) x 2 + (2x) ∑ i: 0..n i + ∑ i: 0..n i 2
= (n + 1) x 2 + n (n + 1) x + n (n + 1) (2n + 1) (⅙)
Таким образом, ваша сумма имеет закрытую форму:
double sum_squares_from(double x, int n) {
return ((n-- > 0)
? (n + 1) * x * x
+ x * n * (n + 1)
+ n * (n + 1) * (2 * n + 1) / 6.
: 0);
}
Если я применю некоторую запутанность, однострочная версия станет:
double sum_squares_from(double x, int n) {
return (n-->0)?(n+1)*(x*x+x*n+n*(2*n+1)/6.):0;
}
Если задача заключается в реализациисуммирование в цикле, используйте хвостовую рекурсию. Хвостовая рекурсия может быть механически заменена циклом, и многие компиляторы реализуют эту оптимизацию.
static double sum_squares_from_loop(double x, int n, double s) {
return (n <= 0) ? s : sum_squares_from_loop(x+1, n-1, s+x*x);
}
double sum_squares_from(double x, int n) {
return sum_squares_from_loop(x, n, 0);
}
В качестве иллюстрации, если вы наблюдаете сгенерированную сборку в GCC на достаточном уровне оптимизации (-Os
, -O2
или -O3
), вы заметите, что рекурсивный вызов исключен (и sum_squares_from_loop
не загружается).
Попробуйте онлайн!