自行打印到控制台的递归阶乘函数 (C#)

recursive factorial function that prints to console on it's own (C#)

这个只是挠痒痒,可能连自己解决的问题都不值得。

我想用 C# 编写一个递归阶乘函数来打印到控制台。问题是,出于好奇,我试图通过只传递函数和参数来让它做到这一点。比如,我想避免输入 Console.WriteLine(Factorial(5));

比我想的更难的是只输入这个并得到结果:

> Factorial(5);

这是我一直在玩的功能:

int Factorial(int number)
{
    Console.Write(number != 1 ? $"{number} x " : $"{number} = \n");
    if (number <= 1) return 1; // end of the line
    number *= Factorial(number - 1); // recursive function
    Console.WriteLine(number);
    return number; // this could have been combined with line above, but more clear this way
}

结果是这样的,而不是看到 2、6 和 24。我只想看到 120:

5 x 4 x 3 x 2 x 1 =
2
6
24
120

给函数增加一个可选参数,表示是否是内部调用,所以签名变成

int Factorial(int number, bool inner=false)

外部调用仍然正常使用Factorial(5),但在内部,更改

number *= Factorial(number - 1);

number *= Factorial(number - 1, true);

然后在打印数字时,检查它是否不是内部的,例如

if (!inner) Console.WriteLine(number);

在递归函数中执行 side-effects,例如计算阶乘通常是一个糟糕的想法,而您尝试做的事情实际上是您不应该做的。

获取答案,然后在调用代码中打印出来。

也就是说,这是实现您所要求的一种糟糕的方法。请不要这样做,我提供这个答案只是为了证明这是可能的。

using System;
using System.Diagnostics;

namespace Test
{
    public static class Program
    {
        static void Main(string[] args)
        {
            var stackTrace = new StackTrace();
            var frames = stackTrace.GetFrames();

            Factorial(5, frames.Length);
        }

        static int Factorial(int number, int frameCount)
        {
            Console.Write(number != 1 ? $"{number} x " : $"{number} = \n");
            if (number <= 1)
            {
                return 1; // end of the line
            }

            number *= Factorial(number - 1, frameCount); // recursive function

            var stackTrace = new StackTrace();
            var frames = stackTrace.GetFrames();

            if (frames.Length == frameCount + 1)
            {
                Console.WriteLine(number);
            }

            return number; // this could have been combined with line above, but more clear this way
        }
    }
}

您可以使用局部函数作为实际的递归部分,使用外部阶乘函数作为调用它的包装器!

int Factorial(int number)
{
    static int DoFactorial(int number) => number <= 1
        ? 1
        : number *= DoFactorial(number - 1);
        
    var answer = DoFactorial(number);
    Console.WriteLine(answer);
    
    return answer;
}