简体   繁体   中英

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

This one is just to scratch an itch, and probably not even a problem worth solving on it's own.

I'd like to write a recursive factorial function to print to the console in C#. The thing is, just out curiosity, I tried to get it to do this by only passing the function and argument. As in, I'd like to avoid having to type Console.WriteLine(Factorial(5));

It's harder that I'd thought to just type this and get a result:

> Factorial(5);

here is the function I've been playing with:

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
}

the results come out like this, where instead of seeing the 2, 6 and 24. I'd just like to see the 120:

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

Add an optional parameter to the function, indicating if it's an inner call, so the signature become

int Factorial(int number, bool inner=false)

outer call still use Factorial(5) normally, but inside, change

number *= Factorial(number - 1); to

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

then on printing the number, check if it's not inner, such as

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

You could use a local function as the actual recursive part, using the outer Factorial function as a wrapper which just calls it!

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;
}

Performing side-effects inside a recursive function like calculating factorial is generally a terrible idea and what you are trying to do is something you really should not.

Get the answer, and then print it out in the calling code.

That said, here is a horrible way to achieve what you asked for. Please do not do this, I only offer this answer to show it is possible.

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
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM