C#에서 팩토리얼(factorial, 계승)을 계산하는 방법은 여러 가지가 있습니다. 이 글에서는 for 루프, while 루프, 재귀(recursion)를 활용한 세 가지 대표적인 방법을 예제 코드와 실행 결과와 함께 살펴봅니다.
팩토리얼은 1부터 n까지의 모든 양의 정수를 곱한 값으로 n!처럼 표기합니다. 예를 들어 5!는 5 × 4 × 3 × 2 × 1이므로 결과값은 120이 됩니다.
1. for 루프로 팩토리얼 계산하기
for 루프를 사용하면 반복 횟수가 명확하게 드러나기 때문에 가장 직관적이고 이해하기 쉬운 방법입니다. 입력값보다 1 작은 수부터 1까지 차례대로 곱하면서 누적하는 방식으로 동작합니다.
예제 코드
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace factorial {
class Test {
static void Main(string[] args) {
int i, res;
int value = 5;
res = value;
for (i = value - 1; i >= 1; i--) {
res = res * i;
}
Console.WriteLine("\nFactorial of " + value + " = " + res);
Console.ReadLine();
}
}
}실행 결과
Factorial of 5 = 120
변수 value에 저장된 5부터 시작해 루프 변수 i가 4, 3, 2, 1 순서로 감소하면서 매번 res에 곱해집니다. 최종적으로 5!인 120이 출력됩니다.
2. while 루프로 팩토리얼 계산하기
while 루프를 사용하면 종료 조건만 명시하면 되므로 로직을 별도의 메서드로 분리하기에 적합합니다. 아래 예제에서는 팩토리얼 계산을 display() 메서드 안에 캡슐화했습니다.
예제 코드
using System;
namespace MyApplication {
class Factorial {
public int display(int n) {
int res = 1;
while (n != 1) {
res = res * n;
n = n - 1;
}
return res;
}
static void Main(string[] args) {
int value = 5;
int ret;
Factorial fact = new Factorial();
ret = fact.display(value);
Console.WriteLine("Value is : {0}", ret);
Console.ReadLine();
}
}
}실행 결과
Value is : 120
n이 1이 아닌 동안에는 계속해서 res에 n을 곱하고 n을 1씩 감소시킵니다. 조건이 거짓이 되면 누적된 결과를 반환합니다.
3. 재귀 함수로 팩토리얼 계산하기
팩토리얼은 수학적으로 n! = n × (n−1)!로 정의되기 때문에 재귀 호출과 잘 맞는 문제입니다. 메서드가 자기 자신을 호출하며 문제를 작게 나누어 해결하는 방식입니다.
예제 코드
using System;
namespace MyApplication {
class Factorial {
public int display(int n) {
if (n == 1)
return 1;
else
return n * display(n - 1);
}
static void Main(string[] args) {
int value = 5;
int ret;
Factorial fact = new Factorial();
ret = fact.display(value);
Console.WriteLine("Value is : {0}", ret);
Console.ReadLine();
}
}
}실행 결과
Value is : 120
n == 1일 때 1을 반환하는 부분이 재귀의 종료 조건(베이스 케이스)입니다. 이 조건이 없으면 무한히 자신을 호출하게 되므로 반드시 포함해야 합니다.
정리: 어떤 방법을 선택할까?
- for 루프: 반복 횟수가 고정적일 때 가장 단순하고 성능 오버헤드가 적습니다.
- while 루프: 조건 기반 반복이 필요할 때 유연하게 사용할 수 있습니다.
- 재귀 호출: 코드가 간결하고 수학적 정의와 일치하지만, 깊은 재귀 시 스택 오버플로 위험이 있으므로 주의해야 합니다.
실무에서는 큰 수의 팩토리얼을 다룰 경우 int 범위를 빠르게 벗어나므로 long이나 BigInteger 타입 사용을 고려하는 것이 좋습니다.