В рекурсивной функции, как я могу перейти к другому вызову функции в стеке? - PullRequest
0 голосов
/ 23 мая 2019

Чтобы сделать мой вопрос более понятным, я приведу пример.Скажем, я хочу реализовать рекурсивную функцию, которая суммирует диапазон чисел от [1-10] и [15-20], пропуская (10-15).Я хотел бы сложить [15-20] и пропустить вызовы функций в стеке (10-15) и продолжить с [1-10].Как я могу это сделать?

int summation(int x, int y) {
    if(x == y) return x;

    // Catch here and return sum of 15-20 back to calls of 1-10
    if(x == 10) 
        catch(int n) 
            return n;

    int sum = x + summation(x+1,y);

    // Skip function calls 10-15
    if(x==15) throw sum;

    return sum;

}

summation(1,20) // >> 160 or [1-10] = 55, [15,20] = 105 

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

Ответы [ 3 ]

3 голосов
/ 23 мая 2019

Для того, чтобы установить попытку / захват в правильном кадре стека, вам нужно знать границу интервала пропуска, прежде чем выполнять более глубокую рекурсию.Учитывая это, будет лучше просто никогда не совершать бесполезные вызовы функций, а не использовать исключение для их раскручивания.Например:

int summation(int const x, int const y)
{
    if(x == y) return x;
    int const next = (x==10)? 15: (x+1);  // skip from 10 to 15 directly
    return x + summation(next, y);
}

Избегание исключений также дает вам возможность написать функцию рекурсивно:

int summation(int const x, int const y, int partial_sum = 0)
{
    partial_sum += x;
    if(x == y) return partial_sum;

    int const next = (x==10)? 15: (x+1);  // skip from 10 to 15 directly
    return summation(next, y, partial_sum);
}
2 голосов
/ 23 мая 2019

Упростите функцию.

int summation(int x, int y) {
    if(x == y) return x;
    return x + summation(x+1,y);
}

и используйте

summation(1, 10) + summation(15, 20);

на стороне клиента.

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

int summation_with_skip(int x1, int x2, int x3, int x4) {
   return summation(x1, x2) + summation(x3, x4);
}

и используйте

summation_with_skip(1, 10, 15, 20);

Если вам нужна логика для пропуска элементов в функции, вы можетеиспользуйте

int summation_with_skip(int x1, int x2, int x3, int x4) 
{
   if ( x1 > x4 )
   {
      return 0;
   }

   int s = summation(x1+1, x2, x3, x4)

   if ( (x1 > x2) && (x1 < x3) )
   {
      return s;
   }
   else
   {
      return x1 + s;
   }
}

Мне нравится идея передать все аргументы функции.

1 голос
/ 23 мая 2019

ну, это было бы решением без броска и ловли

все еще странное решение для данной проблемы

int summation(int x, int y) 
{
    if(x > y) return 0;

    if ((x >= 10) && (x <= 15))
    {
        return summation(x+1, y);
    }
    else
    {
        return x + summation(x+1, y);   
    }
}
...