Как найти сумму ряда с рекурсией

Improve Article

Save Article

Like Article

  • Read
  • Discuss
  • Improve Article

    Save Article

    Like Article

    Given an integer n, the task is to find the sum of the series 11 + 22 + 33 + ….. + nn using recursion.

    Examples: 

    Input: n = 2 
    Output:
    11 + 22 = 1 + 4 = 5 

    Input: n = 3 
    Output: 32 
    11 + 22 + 33 = 1 + 4 + 27 = 32 

    Approach: Starting from n, start adding all the terms of the series one by one with the value of n getting decremented by 1 in each recursive call until the value of n = 1 for which return 1 as 11 = 1.

    Below is the implementation of the above approach:
     

    C++

    #include <bits/stdc++.h>

    using namespace std;

    #define ll long long int

    ll sum(int n)

    {

        if (n == 1)

            return 1;

        else

            return ((ll)pow(n, n) + sum(n - 1));

    }

    int main()

    {

        int n = 2;

        cout << sum(n);

        return 0;

    }

    Java

    class GFG {

        static long sum(int n)

        {

            if (n == 1)

                return 1;

            else

                return ((long)Math.pow(n, n) + sum(n - 1));

        }

        public static void main(String args[])

        {

            int n = 2;

            System.out.println(sum(n));

        }

    }

    Python3

    def sum(n):

        if n == 1:

            return 1

        else:

            return pow(n, n) + sum(n - 1)

    n = 2

    print(sum(n))

    C#

    using System;

    class GFG {

        static long sum(int n)

        {

            if (n == 1)

                return 1;

            else

                return ((long)Math.Pow(n, n) + sum(n - 1));

        }

        public static void Main()

        {

            int n = 2;

            Console.Write(sum(n));

        }

    }

    PHP

    <?php

    function sum($n)

    {

        if ($n == 1)

            return 1;

        else

            return (pow($n, $n) + sum($n - 1));

    }

    $n = 2;

    echo(sum($n));

    ?>

    Javascript

    <script>

    function sum(n)

    {

        if (n == 1)

            return 1;

        else

            return (Math.pow(n, n) + sum(n - 1));

    }

    var n = 2;

    document.write(sum(n));

    </script>

    Time Complexity: O(nlogn), for using pow function for numbers 1 till N.

    Auxiliary Space: O(n) for recursive stack space.

    Last Updated :
    22 Sep, 2022

    Like Article

    Save Article

    WejusT1k

    0 / 0 / 2

    Регистрация: 13.12.2014

    Сообщений: 18

    1

    Вычисление суммы ряда используя рекурсию

    14.02.2015, 21:26. Показов 6746. Ответов 13

    Метки нет (Все метки)


    Студворк — интернет-сервис помощи студентам

    Помогите написать програму для вычисления сумы ряда используя рекурсию
    Я только понял как посчитать факториал (2*N+1)! используя рекурсию, а вот как сумму ряда запрограммировать так и не понял

    C++
    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
    
    #include <iostream>
    #include <math.h>
    using namespace std;
     
    long double fact(int C)
    {
        if(C < 0) // если пользователь ввел отрицательное число
            return 0; // возвращаем ноль
        if (C == 0) // если пользователь ввел ноль,
            return 1; // возвращаем факториал от нуля
        else // Во всех остальных случаях
            return C * fact(C - 1); // делаем рекурсию.
    }
     
    int main()
    {
        int N,x;
        double sum;
        setlocale(0,""); // Включаем кириллицу
        cout << "Введите число для вычисления факториала: ";
        cin >> N;
        int C=2*N+1;
        cout << "Факториал для числа " << C << " = " << fact(C) << endl << endl; // fact(С) - функция для вычисления факториала.
        system("pause");
        return 0;
     
    }

    Сума ряда выглядит так
    https://www.cyberforum.ru/cgi-bin/latex.cgi?sum frac{{-1}^{N}*{x}^{2}}{N*(2*N+1)!}

    Добавлено через 5 минут
    https://www.cyberforum.ru/cgi-bin/latex.cgi?sum frac{{-1}^{N+1}*{x}^{2}}{N*(2*N+1)!}
    Чучуть формулу не так написал, вот она



    0



    183 / 167 / 53

    Регистрация: 27.01.2013

    Сообщений: 788

    14.02.2015, 21:51

    2

    сумма = элемент + сумма_без_элемента



    0



    0 / 0 / 2

    Регистрация: 13.12.2014

    Сообщений: 18

    14.02.2015, 21:53

     [ТС]

    3

    saden, а можете это в коде записать, а то я не понял(



    0



    Эксперт PHP

    4845 / 3857 / 1599

    Регистрация: 24.04.2014

    Сообщений: 11,316

    14.02.2015, 21:55

    4

    WejusT1k, какой диапозон суммирования



    0



    WejusT1k

    0 / 0 / 2

    Регистрация: 13.12.2014

    Сообщений: 18

    14.02.2015, 22:00

     [ТС]

    5

    Jewbacabra,
    диапозон в условии не дан, значит любой который мы введем с клавиатуры, только 0 нужно исключить
    Вот я уже даже часть кода написал, только факториал не могу запилить туда

    C++
    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
    35
    36
    37
    38
    39
    40
    41
    
    #include <iostream>
    #include <math.h>
    using namespace std;
     
    long double fact(int C)
    {
        if(C < 0) // если пользователь ввел отрицательное число
            return 0; // возвращаем ноль
        if (C == 0) // если пользователь ввел ноль,
            return 1; // возвращаем факториал от нуля
        else // Во всех остальных случаях
            return C * fact(C - 1); // делаем рекурсию.
    }
    long double function(int N,int x)
    {
        
        double result;
        double eps=0.00000001;
        if(N <= 0 ) return 0; 
        result = pow(-1,N+1)*pow(x,2) / N(КАК СЮДА ВТУЛИТЬ ФАКТОРИАЛ?);
        if((N == 0) || (result<eps))
            return result;
        else
            return result + function(N - 1,x);
    }
     
    int main()
    {
        int N,x;
        setlocale(0,""); // Включаем кириллицу
        cout << "Введите число для вычисления факториала: ";
        cin >> N;
        cout<<"Введите х n";
        cin>>x;
        int C=2*N+1;
        cout<<"Результат "<<function(N,x)<<"n";
        cout << "Факториал для числа " << C << " = " << fact(C) << endl << endl; // fact(N) - функция для вычисления факториала.
        system("pause");
        return 0;
     
    }



    0



    Эксперт PHP

    4845 / 3857 / 1599

    Регистрация: 24.04.2014

    Сообщений: 11,316

    14.02.2015, 22:05

    6

    Цитата
    Сообщение от WejusT1k
    Посмотреть сообщение

    только факториал не могу запилить туда

    а это не нужно.
    Достаточно выразить a(n+1) через a(n)



    0



    saden

    183 / 167 / 53

    Регистрация: 27.01.2013

    Сообщений: 788

    14.02.2015, 22:14

    7

    C++
    1
    2
    3
    4
    5
    
    double sum(int n)
    { double an = //член ряда, лениво набирать
    if(an<1e-6) return an;//граничная точность счета
    else return an+sum(n+1);
    }

    Добавлено через 2 минуты
    факториал уже набран в начале темы.
    чем не подходит?

    Добавлено через 6 минут
    забыл про х

    C++
    1
    2
    3
    
    double sum(double x,int n=1)//значение по умолчанию позволит делать вызов просто как sum(0.01)
    { ...
    }



    0



    WejusT1k

    0 / 0 / 2

    Регистрация: 13.12.2014

    Сообщений: 18

    14.02.2015, 22:38

     [ТС]

    8

    saden,

    C++
    1
    
    else return an+sum(n+1);

    я вот не понял этой строчки я ввожу с клавиатуры n=100 , суму оно начнет считать с n а потом увеличивать на 1?

    Добавлено через 9 минут
    Jewbacabra,
    я вот сижу так и не могу понять, как сделать, может поможете в написании кода?



    0



    Jewbacabra

    Эксперт PHP

    4845 / 3857 / 1599

    Регистрация: 24.04.2014

    Сообщений: 11,316

    14.02.2015, 22:55

    9

    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    #include <iostream>
    #include <cmath>
    using namespace std;
     
    double rec_sum(double acc, double last, double eps, int i) {
        double next = last * -i / (2 * (i+1) * (i+1) * (2*i+3));
        if (abs(next) < eps) {
            return acc;
        } else {
            return rec_sum(acc+next, next, eps, i+1);
        }
    }
     
    double sum(double x) {
        return rec_sum(-x*x/6, -x*x/6, 1.0e-6, 2);
    }
     
    int main() {
        int x;
        cin >> x;
        cout << sum(x);
        return 0;
    }

    сделал для суммы, где -1^N. Для -1^N+1 домножить результат на -1



    0



    0 / 0 / 2

    Регистрация: 13.12.2014

    Сообщений: 18

    14.02.2015, 23:04

     [ТС]

    10

    Jewbacabra, что то я туплю, даже не понимаю что это за программа



    0



    Эксперт PHP

    4845 / 3857 / 1599

    Регистрация: 24.04.2014

    Сообщений: 11,316

    14.02.2015, 23:11

    11

    Лучший ответ Сообщение было отмечено WejusT1k как решение

    Решение

    WejusT1k, посмотри в этой теме. Большая коллекция решенных задач
    Там решается через цикл, но его легко можно переделать в рекурсию, а основная идея та же



    1



    0 / 0 / 2

    Регистрация: 13.12.2014

    Сообщений: 18

    15.02.2015, 01:35

     [ТС]

    12

    Jewbacabra, через цикл я уже давно сделал, вот только что и с рекурс разобрался,спасибо большое за помощь)

    Добавлено через 1 час 23 минуты
    Думал что разобрался, но все таки нет, кто нибудь помогите и напишите полный код , буду очень благодарен(

    Добавлено через 50 минут
    Кто-нибудь помогите пожалуйста



    0



    saden

    183 / 167 / 53

    Регистрация: 27.01.2013

    Сообщений: 788

    15.02.2015, 08:33

    13

    C++
    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
    
    #include <iostream>
    #include <math.h>
    using namespace std;
     
    long double fact(int C)
    {
        if(C < 0) // если пользователь ввел отрицательное число
            return 0; // возвращаем ноль
        if (C == 0) // если пользователь ввел ноль,
            return 1; // возвращаем факториал от нуля
        else // Во всех остальных случаях
            return C * fact(C - 1); // делаем рекурсию.
    }
     
    double sum(double x,double eps=1e-6,int n=1)//значение по умолчанию позволит делать вызов просто как sum(0.01)
    {  double an = pow(-1,n+1)*pow(x,2) /n/fact(2*n+1);
    if(an<eps) return an;//граничная точность счета
    else return an+sum(x,eps,n+1);
    }
     
    int main()
    {
        double x;
        double sum;
        setlocale(0,""); // Включаем кириллицу
        cout << "Введите число x: ";
        cin >> x;
     
        cout << "Сумма для числа " << x << " = " <<  sum(x) << endl << endl; //sum(x,1e-7) - расчет с другой точностью, sum(x,1e-7,10) - начало счета с 10 элемента
        system("pause");
        return 0;
     
    }



    0



    0 / 0 / 2

    Регистрация: 13.12.2014

    Сообщений: 18

    15.02.2015, 11:45

     [ТС]

    14

    В чем ошибка?

    Добавлено через 15 секунд
    saden, Помогите пожалуйста

    Добавлено через 4 минуты
    saden, Большое спасибо, я разобрался) там просто когда объявляли sum, то мы объявили её как переменную а не функцию



    0



    Например: от 1 до 5 // 1 + 2 + 3 + 4 + 5 = 15

    задан 18 апр 2019 в 11:09

    Serik Shaikamalov's user avatar

    3

    Можно так

    /**
     * Функция находит сумму последовательности чисел используя рекурсию
     * @param begin начало
     * @param end конец
     */
    const sequenceSum = (begin, end) => {
            
        if(begin == 0 && end == 0){
            return 0;
        }else if(begin == end){
            return begin;
        }else if(begin > end){
            return NaN;
        }    
        return begin + sequenceSum(begin + 1, end);            
    };
    
    console.log('Сумма чисел: ', sequenceSum(1,5)); // 15

    ответ дан 18 апр 2019 в 11:12

    Serik Shaikamalov's user avatar

    2

    Существует особый вид рекурсии – хвостовая рекурсия. Такая функция в некоторых случаях эффективнее обычной рекурсивной функции.

    const sumOfSequences = (begin, end) => {
      const iter = (counter, acc) => {
        if (counter === end) {
          return acc + counter;
        }
        return iter(counter + 1, acc += counter);
      };
    
      return iter(begin, 0);
    };
    
    console.log(sumOfSequences(1, 10200));
    

    ответ дан 18 апр 2019 в 11:55

    harryfrese's user avatar

    Рекурсия

    function sum(num) {
        if (num == 0) {
          return 0;
        } else {
          return (num + sum(num - 1));
        }
    }
    
    console.log(sum(5)); // 15
    

    ответ дан 18 апр 2019 в 11:21

    Alexy's user avatar

    AlexyAlexy

    9032 золотых знака8 серебряных знаков19 бронзовых знаков

    const sequenceSum = (begin, end) => {
      if (begin > end) {
        return NaN;
      } else if (begin === end) {
        return begin;
      } else {
        return begin + sequenceSum(begin + 1, end) /*Функция будет вызвана столько раз, пока begin === end */
      }
    }
    

    ответ дан 25 янв 2022 в 15:24

    Евгений Колмак's user avatar

    Евгений КолмакЕвгений Колмак

    4732 золотых знака3 серебряных знака13 бронзовых знаков

    1

    Сумма ряда

    Для начала рассмотрим
    пример суммирования первых n
    членов арифметической прогрессии. Хотя
    такую сумму можно легко вычислить с
    помощью конечной формулы, мы всё же
    посмотрим, как это будет выглядеть на
    Прологе в виде рекурсии.

    Пример 6.
    Для
    вычисления суммы объявим предикат
    sum/3,
    в котором входными аргументами является
    первый член ряда From
    и количество суммируемых членов Count.
    Третий аргумент Summa
    является выходным. Шаг рекурсии для
    простоты равен 1.

    class predicates

    sum : (integer From, unsigned Count, integer Summa)
    procedure (i,i,o).

    Рекурсивный
    предикат будет содержать два предложения:

    clauses

    sum(_,0,0):- !.

    sum(V,Count,Summa) :- sum(V+1,Count-1,Summa1),
    Summa=Summa1+V.

    Первое предложение
    является условием окончания рекурсии
    и содержит условие Count=0,
    для которого значение суммы равно нулю
    Summa=0.
    Это означает, что если ряд не содержит
    членов, то его сумма равна нулю.

    Второе предложение
    собственно суммирует значения членов
    ряда с помощью предиката Summa=Summa1+V.
    Этот предикат можно выразить словами
    так: “сумма n
    членов ряда равна сумме n-1
    членов ряда плюс n-й
    член ряда”. Основной особенностью такой
    рекурсии является то, что суммирование
    производится после рекурсивного вызова,
    другими словами – на выходе из рекурсии.

    Программа
    имеет
    следующий
    код:

    implement main

        open core, console

    constants
    className = “com/visual-prolog/main”.
    classVersion = “$JustDate: $$Revision: $”.

    class predicates
    sum : (integer From, unsigned Count, integer Summa)
    procedure (i,i,o).

    clauses
    classInfo(className, classVersion).

    sum(_,0,0):- !.
    sum(V,Count,Summa) :- sum(V+1,Count-1,Summa1),
    Summa=Summa1+V.

    run():-
       init(),
       sum(1,3,Summa),
       write(Summa),
       write(“nПрограмма завершена”),
       _=readchar().

    end implement main

    goal

       mainExe::run(main::run).

    Запустив программу
    можно увидеть ответ, равный шести.
    Действительно, сумма первых трёх членов
    ряда 1+2+3 равна шести. Замечание:
    предикат sum/3
    в этом примере можно записать более
    лаконично:

    sum(_,0,0):- !.

    sum(V,Count,Summa1+V) :- sum(V+1,Count-1,Summa1).

    Однако в такой
    записи не очевидно то, что вычисления
    производятся на выходе из рекурсии.

    Задание 9.
    Модифицировать предикат из примера 6
    в предикат-функцию со следующим
    объявлением:

    class predicates

    sum : (integer From, unsigned Count, ) -> integer Summa
    procedure (i,i,o).

    Пример 7.
    Суммирование значений членов ряда можно
    производить и перед рекурсивным вызовом,
    другими словами – на входе в рекурсию.
    Для этого в предикат sum/3
    надо добавить ещё один входной аргумент
    Temp,
    в котором мы будем сохранять текущую
    сумму. Назовём
    новый
    предикат
    sum1/4
    и
    объявим
    его
    так:

    class predicates

    sum1 : (integer From, unsigned Count, integer Temp,
    integer Summa)
    procedure (i,i,i,o).

    При вызове этого
    предиката аргумент Temp
    должен быть равен нулю, так как он
    является текущей суммой.

    sum1(_,0,Summa,Summa) :- !.

    sum1(N,Count,Temp,Summa) :-

    sum1(N+1,Count-1,Temp+N,Summa).

    Полный текст
    программы выглядит так:

    implement main

        open core, console

    constants
    className = “com/visual-prolog/main”.
    classVersion = “$JustDate: $$Revision: $”.

    class predicates

    sum1 : (integer From, unsigned Count, integer Temp,
    integer Summa) procedure (i,i,i,o).

    clauses

    classInfo(className, classVersion).

    sum1(_,0,Summa,Summa) :- !.

    sum1(N,Count,Temp,Summa) :-

    sum1(N+1,Count-1,Temp+N,Summa).

    run():-
       init(),

       sum1(1,3,0,Summa1),write(“Ответ=”,Summa1),nl,

       write(“nПрограмма завершена”),

       _=readchar().

    end implement main

    goal

       mainExe::run(main::run).

    Результат работы
    программы будет конечно же таким, как
    и в примере 6.

    Пример 8.
    Этот пример демонстрирует различия
    между двумя способами вычисления суммы
    ряда: с одной стороны сумму можно
    подсчитать на выходе из рекурсии, как
    это сделано в примере 6; с другой
    стороны – на входе в рекурсию, как это
    сделано в примере 7. Второй способ
    расходует стек немного быстрее, чем
    первый. Для демонстрации размера
    используемой памяти применяется предикат
    memory::getUsedStack(),
    который возвращает размер используемого
    стека. Вызывая этот предикат перед
    рекурсивным вызовом и после рекурсивного
    вызова можно наглядно увидеть расход
    памяти на каждом витке цикла:

    implement main

        open core, console

    constants
    className = “com/visual-prolog/main”.
    classVersion = “$JustDate: $$Revision: $”.

    class predicates
    sum : (integer From, unsigned Count, integer Summa)
    procedure (i,i,o).
    sum1 : (integer From, unsigned Count, integer Temp,
    integer Summa) procedure (i,i,i,o).

    clauses
    classInfo(className, classVersion).

    sum(_,0,0) :- write(“Дно Stack=”,memory::getUsedStack(),”   Summa=0″),
    nl,!.
    sum(V,Count,Summa1+V) :-

       write(“Вызов Stack=”,memory::getUsedStack()),nl,
       sum(V+1,Count-1,Summa1),
       writef(“Возврат Stack=%   Summa=%+%=%”,
    memory::getUsedStack(),Summa1,V,Summa1+V),nl.

    sum1(_,0,Summa,Summa) :-

       write(“Дно Stack=”,memory::getUsedStack(),
    ”   Summa=”,Summa),nl,!.
    sum1(N,Count,Temp,Summa) :-

       writef(“Вызов Stack=%   Summa=%+%=%”,
    memory::getUsedStack(),Temp,N,Temp+N),nl,
       sum1(N+1,Count-1,Temp+N,Summa),
       write(“Возврат Stack=”,memory::getUsedStack()),nl.

    run():-
       init(),
       sum(1,3,Summa),write(“Ответ=”,Summa),nl,nl,
       write(“——————————“),nl,nl,
       sum1(1,3,0,Summa1),write(“Ответ=”,Summa1),nl, 
       write(“nПрограмма завершена”),
       _=readchar().

    end implement main

    goal

       mainExe::run(main::run).

    Результаты работы
    этой программы демонстрируют различия
    между двумя способами рекурсий. Предикат
    sum/3
    демонстрирует вычисления на выходе из
    рекурсии, а предикат sum1/4
    – перед входом в рекурсию.

    Задание 10.
    Разработать программу, вычисляющую
    сумму первых пяти случайных чисел,
    возвращаемых функцией Random=math::random(Max).
    Подсказка:
    0 <= Random < Max.

    Соседние файлы в папке Лабораторные работы

    • #

      22.05.2015701.38 Кб18words.txt

    • #
    • #
    • #
    • #
    • #
    • #
    • #
    • #
    • #

    Понятия не имею, что за смешанный способ вам нужен, но сумму этого ряда можно найти два раза взяв производную.

    Пусть f(x) – ваш ряд. Тогда f'(x) = sum (-1)^n x^(2n-2) / (2n+1)

    Чтобы совсем избавиться от знаменателя надо бы, чтобы степень была 2n+1. Можно этого добиться, домножив все на x^3. Потом можно опять взять производную.

    (x^3 f'(x))’ = sum (-1)^n x^2n = sum (-x^2)^n = 1/(1+x^2)

    Теперь назад проинтегрировав это можно получить:
    x^3 f'(x) = arctg(x)+C

    При x=0 слева 0 – значит C=0.

    f'(x) = arctg(x) / x^3

    Отсюда можно найти f'(x): Зайдите на wolframalpha и введите integrate arctg(x)/x^3 dx (не могу дать прямую ссылку с запросом на wolfram, потому что мат-фильтр почему-то срабатывает на ссылку и не дает отправить ответ).

    Чтобы найти константу, придется подставить, например, x=1 и найти сумму ряда a_n = (-1)^n/(4N^2-1). Это какой-то известный сходящийся рад, похоже. Опять, посмотрите на wolframalpha, введите там sum (-1)^n/(4*n^2-1), n=0 to infinity. В итоге получится, что там константа тоже 0.

    Вот и получится, что f(x) =- (x^2 * arctan(x) + arctan(x) + x) / (2x^2)

    Добавить комментарий