【问题标题】:Why do we use a wrapper function for a recursive function?为什么我们对递归函数使用包装函数?
【发布时间】:2020-02-06 13:43:33
【问题描述】:

对递归函数进行包装的目的是什么? 为什么不能直接从主函数调用递归函数呢? 我遇到过一些解释说包装函数有助于更好地传递参数 - 我不明白这一点。

编辑: 考虑一个基于二分搜索的函数的例子,它返回一个峰值元素的索引:

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);  
}

为什么推荐使用包装函数?

【问题讨论】:

  • 你能举个例子吗?
  • 有时为了简单起见使用包装器,例如删除否定或任何东西,以便在递归函数本身中进行较少的检查。这取决于上下文。如果你提供一个例子,有人可能会解释它的目的。
  • 一些原因herehere
  • 谁是“我们”,为什么你认为不能直接调用递归函数?

标签: c++ function recursion wrapper


【解决方案1】:

包装函数可以准备调用递归函数。例如,递归函数具有比用户最初提供的更多参数。或者可以对参数的有效性和测试前置条件进行初步检查。

这是一个用于演示目的的简单示例。

#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

另一个例子是当一个类有一个非静态公共成员函数调用一个静态(私有/受保护)递归成员函数传递给它的类对象的所需数据成员。所以在这种情况下,非静态成员函数提供公共接口,非静态递归函数提供接口的实现。

这是另一个演示程序。

#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;
}

其输出与上图相同。

但这并不意味着总是需要包装函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-17
    • 1970-01-01
    • 2021-01-03
    • 2018-01-02
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    相关资源
    最近更新 更多