Рекурсивные функции - две функции или последний необязательный параметр - PullRequest
2 голосов
/ 12 февраля 2012

При написании рекурсивных функций иногда случается, что что-то должно произойти только на первом проходе рекурсивного алгоритма.Когда это так, у меня есть две опции:

  1. Имеется необязательный параметр под названием «первый запуск», который по умолчанию имеет значение true, но при рекурсивном вызове аргумент равен false
  2. Имеют две функции

Какой вариант предпочтительнее?Если это последнее, как я должен назвать эти функции?(например, если бы он использовал алгоритм заливки, я бы выбрал FloodFill и FloodFillRecursive?)

Заранее спасибо, ell.

Ответы [ 4 ]

4 голосов
/ 12 февраля 2012

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

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

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

1 голос
/ 12 февраля 2012

Если язык позволяет это, то, на мой взгляд, лучше всего иметь одну функцию с официальным «чистым» интерфейсом и использовать локальную функцию (не видимую снаружи) для рекурсии.

Например, в Common Lisp

(defun n-queens (n)
    (let ((result (list)))
      (labels ((place-queen (row free-cols free-diagonals free-counter-diagonals)
                  ...))
        (place-queen 0 ...)
        result)))

или Python

def n_queens(n):
    result = []
    def place_queen(row, free_cols, free_diags, free_counter_diags):
        ...
    place_queen(0, ...)
    return result

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

1 голос
/ 12 февраля 2012

Вариант 2 лучше в каждом случае, о котором я могу подумать. Это зависит от языка, который вы используете, но вы, вероятно, увидите значительно больше (полностью избежать) издержек, передавая каждый раз дополнительный аргумент.

Для соглашения об именах используйте обычное имя для внешней функции (например, FloodFill). Для внутренней функции я бы сказал, что FloodFillRecursive или FloodFillInner - хороший выбор.

1 голос
/ 12 февраля 2012

Это действительно зависит от того, предназначена ли функция для использования сторонними разработчиками. Если это так, может быть предпочтительнее использовать подход двух функций для аккуратности, со второй функцией (FloodFillRecursive), частной / внутренней для вашей библиотеки.

Если это не так, то подход с дополнительными параметрами вполне подходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...