Что такое функция-обертка и как ее использовать? - PullRequest
0 голосов
/ 11 марта 2020

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

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

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

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

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

Ответы [ 4 ]

3 голосов
/ 11 марта 2020

Вы находитесь в правильном направлении.

Перед вызовом существующего рекурсивного метода необходимо проверить параметр и выполнить некоторое действие, если параметр недействителен

Вы не дали подробности о том, что для проверки.

Пример: Если параметр n должен быть в пределах от 1 до 10, вы можете добавить , если , чтобы выполнить эту проверку

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)");
}
2 голосов
/ 11 марта 2020

Хорошо, функция-обертка будет служить цели (иначе не было бы никаких причин для ее существования).

Одной из таких целей может быть проверка правильности ввода перед вызовом фактической рекурсивной функции (как в вашем примере), например, вот так:

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[] для простоты, в реальном мире более вероятно использование обобщенных c массивов или списков):

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

Почему вы хотите использовать функции-оболочки? Существует несколько возможных причин:

  • Сохраняйте рекурсивную функцию как можно более простой.
  • Проверки валидации часто необходимо выполнять один раз, поэтому выполнение этой функции в рекурсивной функции приведет к выполнению ненужного кода ( и, таким образом, приводит к снижению производительности).
  • Обеспечение простой точки входа для вызывающих абонентов и обработка любого сопоставления параметров, настройка и т. д. c. в оболочке.
  • Для рекурсивных функций более общего назначения может потребоваться специальная проверка или настройка, которая применяется только к определенным ситуациям и типам параметров. В этих случаях вы можете захотеть предоставить специальные функции-оболочки для особых случаев, то есть вы снова сделаете рекурсивную функцию максимально простой.
0 голосов
/ 11 марта 2020

Оболочка для рекурсивной функции - это не что иное, как функция, которая отвечает за вызов рекурсивной функции. Почему это используется:
1) Для обеспечения удобного для пользователя способа использования рекурсивной функции (поскольку параметры рекурсивной функции иногда могут быть для пользователя crypti c, и они имеют значения по умолчанию, которые делают функцию работать больше всего времени)
2) Для проверки.

В следующем примере будут показаны все возможные комбинации {0, 1, 2, 3} длиной 4. Функция backtracking() является оберткой для back(int)

. Я написал следующий код на C ++ , если вы хотите перевести его в java, просто замените две функции с функциями stati c в вашем основном классе Java, замените cout на System.out.println();, удалите директиву #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;
}
0 голосов
/ 11 марта 2020

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

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...