Лучший способ условно выполнить функцию? - PullRequest
2 голосов
/ 18 сентября 2009

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

1) Условный возврат:

void myRecursingFunction (int i, int j){
    if (conditionThatWouldStopRecursing) return;
    if (anotherConditionThatWouldStopRecursing) return;
    if (thirdConditionThatWouldStopRecursing) return;

    doSomeCodeHere();
    myRecursingFunction(i + 1, j);
    myRecursingFunction(i, j + 1);
}

2) Оберните все это в выражение if

void myRecursingFunction (int i, int j){
    if (
        !conditionThatWouldStopRecursing &&
        !anotherConditionThatWouldStopRecursing &&
        !thirdConditionThatWouldStopRecursing
    ){
        doSomeCodeHere();
        myRecursingFunction(i + 1, j);
        myRecursingFunction(i, j + 1);
    }
}

3) Вы делаете это неправильно, нуб, ни один здравомыслящий алгоритм никогда не будет использовать рекурсию.

Ответы [ 5 ]

6 голосов
/ 18 сентября 2009

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

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

3 голосов
/ 18 сентября 2009

Если это что-то, что должно быть быстрым, я бы рекомендовал как можно быстрее поразить наиболее распространенный случай (т.е. поставить базовый случай в конец, потому что вы нажмете его только один раз). Также подумайте о том, чтобы поставить базовый регистр-1 перед предложением рекурсии (т.е. выполнить тест перед повторным вызовом функции, а не проверять ее при входе в последующий вызов), если это будет иметь значение.

И, со всеми вещами, не оптимизируйте, если это не проблема. Сначала я пойду для ясности.

3 голосов
/ 18 сентября 2009

Я бы выбрал первое решение, так как это совершенно ясно дает понять, каковы условия остановки рекурсии. Он более читабелен и более удобен в обслуживании.

1 голос
/ 18 сентября 2009

мне больше нравится вариант 1 ...

Гораздо проще читать вариант 2. Здесь вы должны понять 3 отрицания и объединить их все вместе с и. Я знаю, что это не "трудно", но это занимает гораздо больше времени, чем взгляд на вариант 1

0 голосов
/ 18 сентября 2009

Мой голос также за вариант № 1. Мне это кажется понятнее.

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