Почему мы используем функцию-обертку для рекурсивной функции? - PullRequest
0 голосов
/ 06 февраля 2020

Какова цель обертки над рекурсивной функцией? Почему мы не можем напрямую вызвать рекурсивную функцию из главной функции? Я натолкнулся на некоторые объяснения о том, что функция-обертка помогает лучше передавать параметры - я не понимаю этого.

РЕДАКТИРОВАТЬ: рассмотрим пример функции на основе бинарного поиска, которая возвращает индекс элемента пика:

int findPeakUtil(int arr[], int low,  
                 int high, int n)  
{  
    // Find index of middle element  
    int mid = low + (high - low)/2; 



   // Compare middle element with its neighbours (if neighbours exist)  
    if ((mid == 0 || arr[mid - 1] <= arr[mid]) &&  
        (mid == n - 1 || arr[mid + 1] <= arr[mid]))  
        return mid;  

    // If middle element is not peak and its  
    // left neighbour is greater than it, 
    // then left half must have a peak element  
    else if (mid > 0 && arr[mid - 1] > arr[mid])  
        return findPeakUtil(arr, low, (mid - 1), n);  

    // If middle element is not peak and its  
    // right neighbour is greater than it,  
    // then right half must have a peak element  
    else return findPeakUtil(arr, (mid + 1), high, n);  
}  

// A wrapper over recursive function findPeakUtil()  
int findPeak(int arr[], int n)  
{  
    return findPeakUtil(arr, 0, n - 1, n);  
}

Почему рекомендуется использовать функцию оболочки?

1 Ответ

1 голос
/ 06 февраля 2020

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

Вот простой пример, предоставленный для демонстрационной цели.

#include <iostream>
#include <cstring>

char * recursive_reverse( char *s, size_t n )
{
    if ( n < 2 ) return s;

    char c = s[0];
    s[0] = s[n-1];
    s[n-1] = c;

    recursive_reverse( s + 1, n - 2 );

    return s;
}

char * reverse( char *s )
{
    return recursive_reverse( s, std::strlen( s ) );
}

int main() 
{
    char s[] = "Hello DEBNATH KUNDU";

    std::cout << s << '\n';
    std::cout << reverse( s ) << '\n';

    return 0;
}

Вывод программы:

Hello DEBNATH KUNDU
UDNUK HTANBED olleH

Другим примером является случай, когда у класса есть нештатная c publi c функция-член, которая вызывает статическую c (приватную / защищенную) рекурсивную функцию-член, передавая ей необходимые данные-члены объекта класса. Таким образом, в этом случае функция non-stati c предоставляет интерфейс publi c, а функция non-stati c обеспечивает реализацию интерфейса.

Вот еще одна демонстрационная программа.

#include <iostream>
#include <utility>
#include <cstring>

class String
{
private:
    enum Size : size_t { N = 100 };
    char s[N];

    static void recursive_reverse( char *s, size_t n )
    {
        if ( not ( n < 2 ) )
        {
            std::swap( s[0], s[n-1] );
            recursive_reverse( s + 1, n - 2 );
        }
    }       

public:
    explicit String( const char *s )
    {
        strncpy( this->s, s, N );
        this->s[N-1] = '\0';
    }

    void reverse() { recursive_reverse( s, std::strlen( s ) ); }

    friend std::ostream & operator <<( std::ostream &os, const String &s )
    {
        return os << s.s;
    }
};


int main() 
{
    String s(  "Hello DEBNATH KUNDU" );

    std::cout << s << '\n';

    s.reverse();

    std::cout << s << '\n';

    return 0;
}

Его вывод такой же, как показано выше.

Однако это не означает, что всегда требуется функция обертки.

...