Рекурсивная функция для вычитания

Эта функция получает последовательность чисел до тех пор, пока пользователь не введет -1. Он должен возвращать сумму чисел в index(mod3)=0 минус число в других индексах.

Например:

9 2 4 7 8 1 3 -1 

функция сначала суммирует все числа, находящиеся в индексах, кратных трем. Таким образом, sum1 должно быть 5, потому что 4 находится в 3-м индексе, а 1 - в 6-м индексе, все остальные индексы в сумме составляют sum2. Затем он должен вычесть одно из другого: sum1 - sum2 и на выходе должно быть -24 (т.е. сумма1 - сумма2 = 5 - 29 = -24)

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

int sumOfSeq();
void main()
{
    printf("%d\n", sumOfSeq());
    system("pause");
}
int sumOfSeq()
{
    int n, curr = 1, sum1 = 0, sum2 = 0;
    scanf("%d", &n);
    if (n == -1)
        return sum1 - sum2;
    else
    {
        if (curr % 3 == 0)
        {
            sum1 += n;
            curr++;
        }
        else
        {
            sum2 += n;
            curr++;
        }
        sumOfSeq();
    }
}

person Vika Kovaliov    schedule 23.12.2020    source источник


Ответы (2)


Внутри функции sumOfSeq вы не используете сумму, полученную при следующих рекурсивных вызовах функции. Вы просто звоните внутри функции

sumOfSeq();

Так что функция не имеет смысла.

И нет необходимости вычислять две суммы отдельно, потому что в любом случае функция должна вернуть одно значение, результирующую сумму.

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

#include <stdio.h>

long long int sumOfSeq( size_t n )
{
    long long int sum = 0;
    
    int item;
    
    if ( scanf( "%d", &item ) == 1 && item != -1 )
    {
        sum += sumOfSeq( n + 1 ) + ( ( n + 1 ) % 3 == 0 ? item : -item );
    }
    
    return sum;
}

int main(void) 
{
    printf( "%lld\n", sumOfSeq( 0 ) );
    
    return 0;
}

Вывод программы для введенной последовательности чисел

9 2 4 7 8 1 3 -1

is

-24

Как видите, определение функции достаточно простое, и функция использует только один параметр.

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

Также обратите внимание, что согласно стандарту C функция main без параметров должна быть объявлена ​​как

int main( void )

вместо

void main()
person Vlad from Moscow    schedule 23.12.2020

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

Он возвращает 0, поскольку переменные curr, sum1 и sum2 инициализируются значением 0 в начале каждого рекурсивного вызова метода sumOfSeq:

 int n, curr = 1, sum1 = 0, sum2 = 0;

Вместо этого вам нужно передавать самые обновленные значения этих переменных при каждом рекурсивном вызове, например:

int sumOfSeq(int curr, int sum1, int sum2);
void main()
{
    printf("%d\n", sumOfSeq(1, 0, 0));
    system("pause");
}
int sumOfSeq(int curr, int sum1, int sum2)
{
    int n;
    scanf("%d", &n);
    if (n == -1)
         return sum1 - sum2;
    else if (curr % 3 == 0)
         return sumOfSeq(curr + 1, sum1 + n, sum2);
    else
         return sumOfSeq(curr + 1, sum1, sum2 + n);
}

Таким образом, когда вы достигаете условия остановки рекурсии, а именно

if (n == -1)
   return sum1 - sum2;

переменные sum1 и sum2 будут результатом добавления n ко всем этим рекурсивным вызовам.

Можно сократить функцию с помощью тернарного оператора

int sumOfSeq(int curr, int sum1, int sum2)
{
    int n;
    scanf("%d", &n);
    if (n == -1)
        return sum2 - sum1;

    return (curr % 3 == 0) ? sumOfSeq(curr + 1, sum1 + n, sum2) : 
                             sumOfSeq(curr + 1, sum1, sum2 + n);
}
person dreamcrash    schedule 23.12.2020