自行打印到控制台的递归阶乘函数 (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;
}
这个只是挠痒痒,可能连自己解决的问题都不值得。
我想用 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;
}