<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://mediawiki.zeropage.org/index.php?action=history&amp;feed=atom&amp;title=PascalTriangle</id>
	<title>PascalTriangle - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://mediawiki.zeropage.org/index.php?action=history&amp;feed=atom&amp;title=PascalTriangle"/>
	<link rel="alternate" type="text/html" href="https://mediawiki.zeropage.org/index.php?title=PascalTriangle&amp;action=history"/>
	<updated>2026-05-14T13:27:24Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.8</generator>
	<entry>
		<id>https://mediawiki.zeropage.org/index.php?title=PascalTriangle&amp;diff=37461&amp;oldid=prev</id>
		<title>imported&gt;Unknown at 05:24, 7 February 2021</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.zeropage.org/index.php?title=PascalTriangle&amp;diff=37461&amp;oldid=prev"/>
		<updated>2021-02-07T05:24:00Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= 파스칼의 삼각형 알고리즘 =&lt;br /&gt;
* 며칠전에 마감된 자료구조의 첫번째 숙제였죠? 다른 분들도 다르게 짜신 분이 있으시다면 서로 의견을 나눠 보았으면 합니다.&lt;br /&gt;
&lt;br /&gt;
== 재귀 호출을 이용한 방법 - by 인수 ==&lt;br /&gt;
 const int pas(const int &amp;amp;amp;m,const int &amp;amp;amp;n)&lt;br /&gt;
 {&lt;br /&gt;
     if(m==n || n==1) // 행과 열이 같거나(가장 오른쪽이거나) 열이 1일때는 1출력&lt;br /&gt;
         return 1;&lt;br /&gt;
     else&lt;br /&gt;
         return pas(m-1,n-1)+pas(m-1,n); // 재귀호출&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* 보시는 바와 같이.. 졸라 간단합니다.&lt;br /&gt;
* but.. 숫자가 조금만 커져도.. 굉장히 오래 걸립니다. 01학번 이선호군이 32행 정도를 넣어봤을때 걸린 시간은 100초가 넘었다 합니다. 재귀호출.. 될수 있으면 쓰지 맙시다.&lt;br /&gt;
* 이 알고리즘은 시간을 희생하면서 공간을 줄인 알고리즘이겠죠?&lt;br /&gt;
* 뒤를 볼것도 없이 일관적인 알고리즘 -- 선호.&lt;br /&gt;
&lt;br /&gt;
== recursive -zennith ==&lt;br /&gt;
 unsigned long int P(int row, int col) {&lt;br /&gt;
 	/* 열의 값이 행보다 클 경우 종료 */&lt;br /&gt;
 	if(row &amp;amp;lt; col)&lt;br /&gt;
 		exit(0);&lt;br /&gt;
 &lt;br /&gt;
 	/* 주어진 값을 검사하여, 첫번째 열이 1이거나 행과 열이 같은경우 1을 리턴 */&lt;br /&gt;
 	if(col == 1 || row == col)&lt;br /&gt;
 		return 1;&lt;br /&gt;
 &lt;br /&gt;
 	/* 그렇지 않은 경우 행과 열을 1씩 감소해서 재귀 호출한 값과&lt;br /&gt;
 	행만 1 감소시켜 재귀 호출한 값을 더해서 리턴 */&lt;br /&gt;
 	return P(--row, --col) + P(row, ++col);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* 단순히 프린트물의 내용을 옮겼을 뿐..&lt;br /&gt;
&lt;br /&gt;
== 동적 배열을 이용한 방법 - by 인수 ==&lt;br /&gt;
 typedef unsigned long ulong;&lt;br /&gt;
 &lt;br /&gt;
 ulong Pascal_Triangle(int m,int n)&lt;br /&gt;
 {&lt;br /&gt;
 	ulong **Array=new ulong*[m];	// 2차원 동적 배열 할당&lt;br /&gt;
 &lt;br /&gt;
 	for(int i=0;i&amp;amp;lt;m;i++)&lt;br /&gt;
 		Array[i]=new ulong[i+1];	// n행에는 n개의 열만 할당되게&lt;br /&gt;
 &lt;br /&gt;
 	for(i=0;i&amp;amp;lt;m;i++)&lt;br /&gt;
 	{&lt;br /&gt;
 		for(int j=0;j&amp;amp;lt;=i;j++)&lt;br /&gt;
 		{&lt;br /&gt;
 			if(i==j || j==0)		// 행과 열이 같거나 열이 1일때&lt;br /&gt;
 				Array[i][j]=1;		// (배열은 0부터 시작하므로 0이라했음) 1의 값을 줌&lt;br /&gt;
 			else&lt;br /&gt;
 				Array[i][j]=Array[i-1][j-1]+Array[i-1][j];&lt;br /&gt;
 						// 그 외의 경우에는 공식을 따른다.&lt;br /&gt;
 		}&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
 	ulong return_value=Array[m-1][n-1];&lt;br /&gt;
 	// 원하는 값 리턴(역시 배열은 0부터 시작하므로 하나씩 빼서)&lt;br /&gt;
 &lt;br /&gt;
 	if(Array)	// Array 2차원 배열이 할당되었을때&lt;br /&gt;
 	{&lt;br /&gt;
 		for(i=0;i&amp;amp;lt;m;i++)&lt;br /&gt;
 		{&lt;br /&gt;
 			if(Array[i])&lt;br /&gt;
 				delete [] Array[i];		// 지워 준다.(열)&lt;br /&gt;
 		}&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
 	delete [] Array;		// 지워 준다.(행)&lt;br /&gt;
 &lt;br /&gt;
 	return return_value;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* 딱 보기에도 재귀호출보다는 복잡하죠?&lt;br /&gt;
* 그런데.. 속도는 확실히 빠릅니다. 몇백을 넣어도 즉시즉시 나오는..&lt;br /&gt;
* 이 알고리즘은 메모리를 더 쓰면서 속도를 살린 방법이겠죠?&lt;br /&gt;
* 자바로 짜면 좀 더 쉬울거 같네여. 메모리 새는걸 걱정하지 않아도 되니..&lt;br /&gt;
* 다른 좋은 방법이 있으시면 여기다 적어주시기 바랍니다.&lt;br /&gt;
* ㅡ.ㅡ 가..같다.. --선호&lt;br /&gt;
&lt;br /&gt;
== dynamic allocation -zennith ==&lt;br /&gt;
 int P(int row, int col) {&lt;br /&gt;
 	/* 변수 선언부 */&lt;br /&gt;
 	int i, j, temp;&lt;br /&gt;
 &lt;br /&gt;
 	/* 연산을 위해 이중 정수형 포인터 선언 */&lt;br /&gt;
 	int ** buffer;&lt;br /&gt;
 &lt;br /&gt;
 	/* 열이 행보다 클 경우 종료 */&lt;br /&gt;
 	if(col &amp;amp;gt; row)&lt;br /&gt;
 		exit(0);&lt;br /&gt;
 &lt;br /&gt;
 	/* buffer에 행만큼의 정수포인터형을 할당받아 대입 */&lt;br /&gt;
 	buffer = malloc( row * sizeof(int *) );&lt;br /&gt;
 &lt;br /&gt;
 	for(i = 0; i &amp;amp;lt; row; i++) {&lt;br /&gt;
 		/* 각각의 정수 포인터에 정수 배열을 할당한다 */&lt;br /&gt;
 		*(buffer + i) = (int *)malloc( (i + 1) * sizeof(int) );&lt;br /&gt;
 &lt;br /&gt;
 		/* 할당을 실패했을 때 */&lt;br /&gt;
 		if(*(buffer + i) == NULL) {&lt;br /&gt;
 &lt;br /&gt;
 			/* 먼저 여태까지 할당한 정수 배열을 반환 하고 */&lt;br /&gt;
 			for(j = 0; j &amp;amp;lt;= i; j++) {&lt;br /&gt;
 				free(*(buffer + j));&lt;br /&gt;
 			}&lt;br /&gt;
 &lt;br /&gt;
 			/* 정수 포인터 배열을 반환 한 후 */&lt;br /&gt;
 			free(buffer);&lt;br /&gt;
 &lt;br /&gt;
 			/* 종료한다 */&lt;br /&gt;
 			exit(0);&lt;br /&gt;
 		}&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
 	/* 연산부 */&lt;br /&gt;
 	for(i = 0; i &amp;amp;lt; row; i++) {&lt;br /&gt;
 		for(j = 0; j &amp;amp;lt;= i; j++) {&lt;br /&gt;
 			/* 열이 1이거나 행과 열이 같은 경우, 1을 대입 한다 */&lt;br /&gt;
 			if(j == 0 || j == i) {&lt;br /&gt;
 				*(*(buffer + i) + j) = 1;&lt;br /&gt;
 				continue;&lt;br /&gt;
 			}&lt;br /&gt;
 &lt;br /&gt;
 			/* 그렇지 않은 경우 전 행(i - 1) 전 열(j - 1)의 값과,&lt;br /&gt;
 			전 행(i - 1) 동 열(j) 의 값을 더해서 대입한다 */&lt;br /&gt;
 			*(*(buffer + i) + j) =&lt;br /&gt;
 				*(*(buffer + i - 1) + j - 1) + *(*(buffer + i - 1) + j);&lt;br /&gt;
 		}&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
 	/* 계산한 결과값을 임시변수에 저장한다 */&lt;br /&gt;
 	temp = *(*(buffer + row - 1) + col - 1);&lt;br /&gt;
 &lt;br /&gt;
 	/* 먼저 정수 배열을 반환하고 */&lt;br /&gt;
 	for(i = 0; i &amp;amp;lt; row; i++)&lt;br /&gt;
 		free(*(buffer + i));&lt;br /&gt;
 &lt;br /&gt;
 	/* 정수 포인터 배열을 반환한다 */&lt;br /&gt;
 	free(buffer);&lt;br /&gt;
 &lt;br /&gt;
 	/* 임시변수에 저장한 값을 리턴 */&lt;br /&gt;
 	return temp;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* 아직 개선할점이 한 두 군데 있는데.. 구지 여기에 올린 이유는 저게 Null pointer assignment 에러가 나서.. 에러난걸 왜 올리는데. 라고 하시면 할말 없지만.. 혹시 혜안으로 시원하게 찔러주실 분 지적해주시면 감사하겠습니다.&lt;br /&gt;
* 해결했습니다. 문제 없이 돌아가는군요.. 역시 포인터는 어렵고 어려워라..&lt;br /&gt;
&lt;br /&gt;
== 첫줄부터 쭉 계산하는 방법 ==&lt;br /&gt;
 // 첫행부터 n행까지 계산하는 방법을 통해&lt;br /&gt;
 // 파스칼의 삼각형의 n행 m열의 값을 구하는 함수 (34행 까지 계산 가능)&lt;br /&gt;
 unsigned long PascalTriangle1(int n, int m)&lt;br /&gt;
 {&lt;br /&gt;
 	if(n&amp;amp;lt;0 || n&amp;amp;gt;35 || m&amp;amp;lt;0 || m&amp;amp;gt;n)	// 행과 열의 값이 잘못된경우 0을 리턴&lt;br /&gt;
 		return 0;&lt;br /&gt;
 	if(n==1 || n==2)	// 1행 또는 2행은 모두 1 이므로 1을 리턴&lt;br /&gt;
 		return 1;&lt;br /&gt;
 &lt;br /&gt;
     // 2개의 배열을 사용하여 계산을 한다&lt;br /&gt;
 	// 하나의 배열에 2행을 저장한 후&lt;br /&gt;
 	// 그 배열을 사용해 3행을 계산해 나머지 배열에 저장하고&lt;br /&gt;
 	// 다시 3행이 저장된 배열을 사용해 4행을 계산해서&lt;br /&gt;
 	// 2행이 저장되어 있던 배열에 저장하고&lt;br /&gt;
 	// 계속 이와같은 식으로 n행 까지 계산한다&lt;br /&gt;
 &lt;br /&gt;
 	unsigned long *row[2];	// 2개의 배열의 포인터&lt;br /&gt;
 	row[0]=new unsigned long[40];	// 최대 40열까지 저장할 수 있도록 메모리 할당&lt;br /&gt;
 	row[1]=new unsigned long[40];&lt;br /&gt;
 	row[0][0]=row[0][1]=1;	// 2행을 저장한다&lt;br /&gt;
 	int current=0;	// 2개의 배열 중 계산중인 배열을 나타내는 변수&lt;br /&gt;
 &lt;br /&gt;
 	for(int i=3;i&amp;amp;lt;=n;i++)	// 3행부터 n행까지 계산&lt;br /&gt;
 	{&lt;br /&gt;
 		current=!current;	// 계산할 배열을 바꿈&lt;br /&gt;
 &lt;br /&gt;
 		row[current][0]=1;	// 첫번째 열은 항상 1&lt;br /&gt;
 		row[current][i-1]=1;	// 마지막 열도 항상 1&lt;br /&gt;
 &lt;br /&gt;
 		for(int j=1;j&amp;amp;lt;i-1;j++)	// 나머지 열을 계산&lt;br /&gt;
 			row[current][j]=row[!current][j-1]+row[!current][j];&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
 	// n행 m열의 값을 보관&lt;br /&gt;
 	unsigned long temp=row[current][m-1];&lt;br /&gt;
 	delete[] row[0];	// 할당했던 메모리 해제&lt;br /&gt;
 	delete[] row[1];&lt;br /&gt;
 	return temp;	// 보관해둔 n행 m열의 값을 리턴&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
== 조합의 수를 이용한 방법 ==&lt;br /&gt;
 // 조합의 수를 계산하는 방법을 통해&lt;br /&gt;
 // 파스칼의 삼각형의 n행 m열의 값을 구하는 함수 (17행까지 계산 가능)&lt;br /&gt;
 unsigned long PascalTriangle2(int n, int m)&lt;br /&gt;
 {&lt;br /&gt;
 	if(n&amp;amp;lt;0 || n&amp;amp;gt;18 || m&amp;amp;lt;0 || m&amp;amp;gt;n)	// 행과 열의 값이 잘못된 경우 0을 리턴&lt;br /&gt;
 		return 0;&lt;br /&gt;
 	if(n==1 || n==2)	// 1행 또는 2행은 모두 1 이므로 1을 리턴&lt;br /&gt;
 		return 1;&lt;br /&gt;
 	// 5행 1열과 5행 5열, 5행 2열과 5행 4열 등은&lt;br /&gt;
 	// 값이 같지만 5행 1열이나, 5행 2열이 계산이 간단하여&lt;br /&gt;
 	// 계산중에 오버플로우가 일어나는 경우를 줄일수 있어&lt;br /&gt;
 	// 더욱 많은 행을 계산할 수 있다&lt;br /&gt;
 	// 5행 5열이나, 5행 4열과 같은 것을 5행 1열이나, 5행 2열로&lt;br /&gt;
 	// 바꿔서 다시 호출해주는 부분이다&lt;br /&gt;
 	if(m&amp;amp;gt;n/2+n%2)&lt;br /&gt;
 		return PascalTriangle2(n,n-m+1);&lt;br /&gt;
 &lt;br /&gt;
 	unsigned long x=1,y=1, p;&lt;br /&gt;
 &lt;br /&gt;
     // (n-1)!/((n-1)-(m-1))! 을 계산&lt;br /&gt;
 	p=n-1;&lt;br /&gt;
 	for(int i=0;i&amp;amp;lt;m-1;i++)&lt;br /&gt;
 	{&lt;br /&gt;
 		x*=p;&lt;br /&gt;
 		p--;&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
 	// (m-1)! 을 계산&lt;br /&gt;
 	for(p=m-1;p&amp;amp;gt;=2;p--)&lt;br /&gt;
 		y*=p;&lt;br /&gt;
 &lt;br /&gt;
 	return x/y;	// (n-1)!/(((n-1)-(m-1))!*(m-1)!) 을 리턴&lt;br /&gt;
 }&lt;br /&gt;
----&lt;br /&gt;
[[문제분류]]&lt;br /&gt;
&lt;/div&gt;</summary>
		<author><name>imported&gt;Unknown</name></author>
	</entry>
</feed>