什么是包装函数以及如何使用它?

what is wrapper function and how to use it?

我的作业要求我使用一个名为包装函数的函数来验证递归函数的参数,我不明白这是什么意思。我从包装函数中了解到的是它什么都不做,只是包装一个函数,例如:

private static int recursive(int n){
    //do something
    .
    .
    .
}

public static int recursiveWrap(int n){
    return recursive(n);
}

我什至不知道上面的代码是否是包装器的正确实现,但我知道它对递归函数没有任何作用,只是冗余。

我应该如何使用包装函数来验证参数?我的递归函数有一个基本情况,它将在没有包装器帮助的情况下达到。

你的方向是正确的。

在调用现有的递归方法之前,需要对参数进行验证,如果参数无效则采取一些操作

您没有详细说明要验证的内容。

例子:如果参数n应该在1到10之间,你可以添加一个if检查来做该验证

public static int recursiveWrap(int n) {
    if (n < 0 || n > 10) {
       //some action
    }
    return recursive(n);
}

一些操作 - 可以是抛出异常或返回默认结果(可能在记录警告消息之后)。

在Java中,通常抛出一个IllegalArgumentException表示传递的参数无效。

if (n < 0 || n > 10) {
    throw new IllegalArgumentException("The parameter value must be between 1 and 10 (inclusive)");
}

根据我对该主题的快速研究,目标似乎是在调用递归函数之前让函数验证整数以避免错误。例如,如果我正在编写一个计算整数阶乘的递归函数,我想在调用我的方法之前确保整数是正数或零。

public int factorial(int n)
{
    if(n == 0)
    {
         return 1;
    }
    return n * factorial(n-1);
}

public int factorialWrapper(int n)
{
    if(n < 0)
    {
        return 0;
    }
    return factorial(n);
}

好吧,包装函数是有用途的(否则它就没有存在的理由了)。

一个这样的目的可能是在调用实际的递归函数之前首先验证输入(如您的示例中的情况),例如像这样:

public static int recursive(int n){
   //do something
   .
   .
   .
}

public static int recursiveWrap(int n){
   if( n < 0 ) {
     throw new IllegalArgumentException("only positive arguments are allowed");
   }
   return recursive(n); 
}

另一个目的可能是为递归提供一个方便的入口点,例如对于快速排序(出于简单原因,我将只使用 int[],真实世界的示例更可能使用通用数组或列表):

private static void recursiveQS(int[] array, int left, int right) {
  //actual implementation here
}

//that's what the user would call
public static void quickSort(int[] array) {
   recursiveQS(array, 0, array.length);
}

为什么要使用包装函数?有多种可能的原因:

  • 使递归函数尽可能简单。
  • 验证检查通常需要进行一次,因此在递归函数中进行验证会执行不必​​要的代码(从而导致性能下降)。
  • 为调用者提供一个简单的入口点并处理包装器中的任何参数映射、设置等。
  • 对于更通用的递归函数,可能有仅适用于特定情况和参数类型的特殊验证或设置。在这些情况下,您可能希望为特殊情况提供特殊包装函数,即您再次使递归函数尽可能简单。

递归函数的包装器只不过是一个具有以下功能的函数 调用递归函数的责任。 为什么使用:
1) 为用户提供一种使用递归函数的用户友好方式(因为递归函数的参数有时对用户来说可能是神秘的,并且它们具有使函数在大多数时间工作的默认值)
2)用于验证。

下面的例子将显示{0, 1, 2, 3}所有可能的组合 长度为 4。函数 backtracking()back(int)

的包装器

下面的代码我是用C++写的,如果要翻译成java就好了 用 Java main class 中的静态函数替换这两个函数,用 System.out.println(); 替换 cout,删除 #include 指令和 `using namespace std; 它将起作用;

#include<iostream>
using namespace std;

int a[4];

void back(int i)
{
  if(i == 4)
  {
    for(int j = 0;j < 4;j++)
    cout << a[j] << ' ';

    cout << endl;
  }
  for(int j = 0; j < 4; j++)
  {
    a[i] = j;
    back(i+1);
  }
}

void backtracking() {
  back(0);
}

int main() {
   backtracking();
   return 0;
}