본문 바로가기
C Programming/예제 프로그램

[C Console] 시그마 팩토리얼 수식 계산 프로그램(재귀, 이중 for문, 단일 for문)

by 희품 2019. 5. 21.
반응형

팩토리얼과 시그마( ∑ )

팩토리얼(Factorial)은 계승이라고도 하며, 수학에서 특정 자연수의 수보다 작거나 같은 모든 양의 정수의 곱을 의미합니다. ∑(시그마)는 급수라고도 하며, 수열의 모든 항을 더하는 기호입니다.

여기서 C언어로 아래의 수식을 3가지 방법으로 표현해보겠습니다.

시그마 팩토리얼

팩토리얼 k! = 1 * 2 * 3 * ... * (k-1) * k로 나타낼 수 있습니다.

따라서 위의 구하고자 하는 수식은 아래와 같이 풀어서 쓸 수 있습니다.

S(k!) = 1 + (1 * 2) + (1 * 2 * 3) + ... + (1 * 2 * 3 * ... * k-1) + (1 * 2 * 3 * ... * (k-1) * k)

시그마 팩토리얼 알고리즘의 성질

주의하실 점은 자연수의 곱셈이다 보니, 팩토리얼을 계산할 때, 0을 곱하는 순간 모든 값은 0이 되어버리기 때문에 1부터 시작하거나 1로 끝나야 되는 점입니다.

 

수식에 의미대로 팩토리얼을 계산하는 반복, 시그마를 계산하는 반복을 사용해서 2중 반복문으로 표현이 가능하고, 순차적으로 늘어나는 시그마의 성질을 이용해서, 합을 계산하는 시그마 반복문 안에 팩토리얼 알고리즘을 녹여 1개의 반복문으로도 구현할 수 있습니다.

 

또 팩토리얼은 순차적인 자연수의 곱이기 때문에 재귀 함수로 구현이 가능합니다.

이중 for문을 사용하는 방법, 단일 for문을 사용하는 방법, 재귀 함수와 단일 for문을 사용하는 3가지 방법으로 시그마 팩토리얼 수식을 계산하는 프로그램입니다.

 

예제 코드 및 설명

int CalcSigmaFactorial() 함수는 flag에 따라 다른 로직으로 시그마 팩토리얼 합계를 구하고 있습니다.

flag 값이 0 이면 팩토리얼 계산을 재귀 함수로, 1이면 이중 for문으로, 2이면 단일 for문으로 계산해서 값을 반환합니다.

(모두 값이 동일하게 나오는 것을 확인할 수 있습니다.)

 

이중 for문의 경우, 반복문을 통해 구한 팩토리얼 값을 시그마 반복문에 더해서 계산을 하는 방법이고, 단일 for문은 시그마의 성질을 이용해 1부터 구하려는 값까지 순차적으로 팩토리얼 값을 반복해서 더하는 방법입니다. 재귀 함수를 이용한 방법은 팩토리얼 값을 재귀 함수로 구하고, 시그마 반복문을 통해 값을 반환하는 방법입니다.

//=============================================
/**
* @file		main.c
* @brief	시그마 팩토리얼을 계산해서 반환하는 프로그램

* @author	fosterahope.tistory.com
*///===========================================
#include <stdio.h>

int CalcSigmaFactorial(int value, int flag);
int calcFactorial(int n);

//==========================================================================
/**
* @brief	Entry 함수(main)
* @return	int
*///========================================================================
int main(void)
{
	int nValue = 0, nSigma = 0;
	printf("계산할 n 값을 입력하세요 : ");
	scanf_s("%d", &nValue);
		
	printf("%d까지의 시그마 합계는 %d 입니다.(재귀)\n", nValue, CalcSigmaFactorial(nValue, 0));
	printf("%d까지의 시그마 합계는 %d 입니다.(이중 루프)\n", nValue, CalcSigmaFactorial(nValue, 1));
	printf("%d까지의 시그마 합계는 %d 입니다.(단일 루프)\n", nValue, CalcSigmaFactorial(nValue, 2));

	return 0;
}
//==========================================================================
/**
* @brief	시그마 팩토리얼 수식을 계산해서 반환해주는 함수

* @param	int n		  :	[IN] 계산할 인자 값(value!)
* @param	int logicFlag : [IN] 0 : 재귀 함수, 1 : 이중 반복문, 2 : 단일 반복문

* @return	int : 팩토리얼 계산된 반환 값
*///========================================================================
int CalcSigmaFactorial(int n, int logicFlag)
{
	int nSigmaSum = 0;	// Sigma Factorial 총 합
	int stepSum = 1;	// Sigma 각 항의 Factorial 합
	if (logicFlag == 1)
	{
		// 이중 반복문
		for (int nSig = 1; nSig <= n; nSig++)
		{
			for (int nFact = 1; nFact <= nSig; nFact++)
			{
				// 각 항의 팩토리얼 계산
				stepSum *= nFact;
			}
			nSigmaSum += stepSum;

			stepSum = 1; // 팩토리얼 초기화
		}
	}
	else if (logicFlag == 2)
	{
		// 단일 반복문
		int nStep = 1; // 1부터 곱한다.
		for (int i = 1; i <= n; i++)
		{
			stepSum *= nStep;
			nSigmaSum += stepSum;
			nStep++;
		}
	}
	else
	{
		// 재귀 함수
		for (int i = 1; i <= n; i++)
		{
			nSigmaSum += calcFactorial(i);
		}
	}

	return nSigmaSum;
}

//==========================================================================
/**
* @brief	재귀함수로 팩토리얼 수식을 계산해서 반환해주는 함수

* @param	int n : [IN] 계산할 팩토리얼 수

* @return	int : 계산된 팩토리얼 값
*///========================================================================
int calcFactorial(int n)
{
	if (n <= 1)
		return 1;

	return n * calcFactorial(n - 1);
}

 

함수를 사용하지 않고 이중 for문으로 계산하는 코드입니다. 역시 같은 값이 나오죠?

//=============================================
/**
* @file		main.c
* @brief	시그마 팩토리얼을 계산해서 반환하는 프로그램

* @author	fosterahope.tistory.com
*///===========================================
#include <stdio.h>

//==========================================================================
/**
* @brief	Entry 함수(main)
* @return	int
*///========================================================================
int main(void)
{
	int nValue = 0, nSigma = 0;
	int nFact = 1;
	printf("계산할 n 값을 입력하세요 : ");
	scanf_s("%d", &nValue);

	for (int i = 1; i <= nValue; i++)
	{
		for (int j = 1; j <= i; j++)
		{
			nFact *= j;
		}
		nSigma += nFact;
		nFact = 1;
	}
		
	printf("%d까지의 시그마 합계는 %d 입니다.\n", nValue, nSigma);

	return 0;
}

S(5!) : 1 + 1*2 + 1*2*3 + 1*2*3*4 + 1*2*3*4*5 = 153입니다.

시그마와 팩토리얼 알고리즘, 유사하게 구현하시면 될 것 같습니다.

 

 

 

반응형