C# с использованием рекурсии только с одним возвратом

У меня есть следующая рекурсивная функция

public int Factorial(int number_to_calculate)
{
    if (StackChanged != null)
    {
        StackChanged(new CustomEventArgs(StackValue, Result));
    }

    System.Threading.Thread.Sleep(wait_time);
    if (number_to_calculate == 0)
    {
        StackValue--;
        return 1;
    }
    else
    {
        StackValue++;
        Result = (number_to_calculate * Factorial(number_to_calculate - 1));
    }

    if (StackChanged != null)
    {
        StackChanged(new CustomEventArgs(StackValue, Result));
    }
    StackValue--;
    System.Threading.Thread.Sleep(wait_time);
    return Result;
}

По-видимому, мой супервизор не согласен с тем, что у меня 2 возврата, но хочет, чтобы функция была рекурсивной. Так что мне нужно только одно возвращение. Я уже пытался использовать аккумулятор с началом goto, чтобы получить только один возврат, но мне нужно увеличивать StackValue каждый раз, когда функция вызывает себя, и уменьшать его, когда она выходит из рекурсии. Таким образом, я не буду знать, когда он выйдет.

У кого-нибудь есть какие-либо идеи?

3 ответа

Решение

Вместо

if (number_to_calculate == 0)
    {

        StackValue--;

        return 1;

    }...

делать

if (number_to_calculate == 0)
    {

       result = 1;

    }

Самый простой способ сделать функцию с одним оператором return - сохранить значение, которое нужно вернуть, в переменной, а затем вернуть его в конце. Таким образом, вы должны преобразовать что-то вроде следующего:

int myFunc() {
    if (cond)
        return x;
    else
        return y;
}

На что-то вроде этого:

int myFunc() {
    int returnValue;
    if (cond)
        returnValue = x;
    else
        returnValue = y;
    return returnValue;
}

Этот принцип может быть применен в целом к ​​любому методу, если вы позаботитесь о том, чтобы при изменении оператора возврата на присвоение переменной у вас была настройка условий, поэтому остальная часть кода будет пропущена.

Однако подобное требование довольно произвольно. В общем случае ожидается, что с рекурсией будет несколько операторов return.

int Factorial(int number) 
        {
            int result = 1;
            StackValue++;
            if (StackChanged != null)
                StackChanged(new CustomEventArgs(StackValue, Result));

            if (number > 1) 
            {       
                System.Threading.Thread.Sleep(wait_time); 
                result = number * Factorial(number - 1);
            }

            StackValue--;
            if (StackChanged != null)
                StackChanged(new CustomEventArgs(StackValue, Result));

            return result;
        }
Другие вопросы по тегам