• Like
자료구조 Project1
Upcoming SlideShare
Loading in...5
×
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
216
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
0
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. C1 조Project #1파스칼의 삼각형C12012-03-17
  • 2. 목차1. 프로젝트 수행 결과 보고서 ............................................................................................................ 3프로젝트의 목적 ..................................................................................................................................... 3프로젝트의 내용 ..................................................................................................................................... 3프로젝트의 진행 방법 ............................................................................................................................ 3프로젝트 결과 ......................................................................................................................................... 3참고문헌 및 웹 ....................................................................................................................................... 32. 프로젝트 수행 일지 ........................................................................................................................... 43월 6일 프로젝트 착수 .......................................................................................................................... 43월 10일 일정계획 및 진행방법 토의 .................................................................................................. 53월 13일 업무 분담 및 1차 소스 작성 ................................................................................................ 53월 15일 2차 소스 작성 ........................................................................................................................ 63월 18일 소스 완료 및 최종보고서 작성 ............................................................................................. 73월 20일 최종 소스 작성 및 최종보고서 검토 .................................................................................. 10
  • 3. 1. 프로젝트 수행 결과 보고서프로젝트의 목적 - 배열의 사용법을 안다. - 프로그램의 시간,공간 복잡도를 계산할 수 있다.프로젝트의 내용 - 배열을 이용하여 파스칼의 삼각형을 출력하는 프로그램을 작성하고, 시간 복잡도와 공간 복잡도를 이용하여 보다 빠르고 메모리 손실이 작은 프로그램을 만들자.프로젝트의 진행 방법 - 전체적인 프로젝트 진행은 팀원들과의 협동을 통해 진행되며 각자의 역할을 분담하여 프 로젝트 진행 속도와 완성도를 높이는 방향으로 진행된다.프로젝트 결과 - 50행 이하의 파스칼의 삼각형 출력에는 문제가 없으나 그 이상의 행에서는 소수점 이하 의 오차가 발생하는 프로그램이 완성되었다. - 최종 검토 과정에서 생각지 못한 오류와 불필요한 메모리 손실이 발견되어 재 수정을 거 쳤고 오차와 메모리손실을 줄였다.참고문헌 및 웹http://10albatross.tistory.com/27http://carstart.tistory.com/122http://skmagic.tistory.com/164
  • 4. http://qwe1qwe.tistory.com/880C로 쓴 자료구조론_HOROWITZ,Sahni,Anderson-Freed저 , wikepedia.org , httpispkorea.com , 2. 프로젝트 수행 일지3월 6일 프로젝트 착수 - 조 편성 및 프로젝트 문제 인식 - 문제 인식 :배열을 이용하여 파스칼의 삼각형을 문제에서 요구하는 대로 출력 해야한다. 사실상 파스칼의 삼각형 출력은 어려운 것이 아니다. 하지만, 자료형 제한과 메모리와 시간의 균형을 맞추는 것이 매우 어려울 것이다. - 파스칼의 삼각형이란?
  • 5. 3월 10일 일정계획 및 진행방법 토의 - 일정계획 및 진행방법 토의 - 일정계획: 3월 13일 2차 미팅 – 업무 분담 및 1차 소스 작성 3월 15일 3차 미팅 – 2차 소스 작성 및 오차 수정 3월 18일 4차 미팅 – 소스 완료 및 최종 보고서 작성 3월 19일 5차 미팅 – 최종보고서 검토 및 프로젝트 완료 3월 20일 6차 미팅 – 최종보고서 검토내용 적용 및 소스 수정 3월 22일 프로젝트 마감 제출 발표 - 진행방법:토론과 토의를 바탕으로 프로젝트를 수행하며, 팀 내에서 업무분담을 통해 작업 의 효용성을 높이며 토의와 수정을 거쳐 완성도 높은 프로젝트 결과물을 도출한다. 소스 작성에 있어서는 배열을 먼저 선언하고 출력 하는 방법을 고려한다.3월 13일 업무 분담 및 1차 소스 작성 - 업무분담 : 조장 : 09학번 최고봉 – 최종보고서작성, 발표 팀원 : 08학번 고충욱– 자료조사, 보고서작성 11학번 서상현 – 보고서작성, 스케쥴링 11학번 김성진 – 소스작성, 자료조사 11학번 김지환 – 자료조사, 스케쥴링 - 1차 소스 작성 당초 생각했던 배열을 먼저 선언하고 출력하는 방식은 메모리손실이 크고 시간이 오래 걸릴것으로 예상되므로 재귀함수를 이용하는 방법을 이용하기로 했다. #include <stdio.h> int Sum (int n, int m, int *sum); // Sum 함수선언 int Sum (int n, int m, int *sum) // Sum 함수정의 (n-1)(m-1)+(n-1)(m)을 이용한다. { If (m < = 1 ) // m이 1이되면 값은 무조건 1이기 때문에 , 걸러준다.
  • 6. { sum += 1; // 조건에 걸릴경우 sum 에 1을 더해주어 값을 더한다. Break ; } If(n<m) Break; // m이 n보다 커지는경우가 발생하면 바로 종료시켜준다. Sum(n-1,m-1,sum); // (n-1)(m-1)에 해당하는 부분이다. Sum(n-1,m,sum); // (n-1)(m)에 해당하는 부분이다. } Int main (void) { Intn,m,sum; + Sum = 0; Scanf(“%d %d”, &n , &m); Sum(n,m,sum); //(n,m)을 함수에 대입시킨다. Printf(“%d”, sum); Return 0;} 이 방법은 자료형 제한과 시간적인 결함으로 인해 보완할 점이 많다. 라는 결론을 내렸 다.3월 15일 2차 소스 작성 - 3월 13일 작성한 소스가 자료형의 제한에 걸리는 동시에 시간이 오래 걸린다는 오점이 있었고, 그래서 우리는 공식을 저장하고 그 공식에 입력 받은 값을 대입하여 값을 얻어내 는 방법을 이용한 소스를 작성하기로 하였다. 하지만 새로운 소스는 메모리 손실이 크다 는 오점이 있다. #include <stdio.h> Intmain(void) { Intn,m,sum,p,r,I,k; //연산을 위한 변수와 숫자를 대입받을 변수선언 Scnaf(“%d %d”, &n,&m); // n 과 m 을 대입받는다.
  • 7. P = r = 1; //곱셈연산을 하기위해 초기값을 1 로 설정 For(i=1;i<m;i++) // r! 을 구한다. r *= i; k = m-1; for(i=n-1;;i--) // nPr을 구한다. { If(k==0) Break; k--; p *= i; } sum = p/r; // nPr / r! 을 연산한다. Printf(“%d”, sum); // 출력. Return 0; }3월 18일 소스 완료 및 최종보고서 작성 - 우리는 메모리보다는 실행시간에 중점을 두고 프로젝트를 진행 해왔고, 앞서 작성한 두 소스 (재귀함수이용,공식대입)중에 공식대입소스를 이용하기로 하였다. 소스 검토 과정중 에 마주한 어려움으로는 자료형의크기제한으로 인한 오류와 연산의 어려움 이였다. 이를 해결하기 위하여 배열을 크게 선언하여 공간을 확보하여 배열에 결과값을 저장하는 방식 을 통해 결과값을 출력하기로 하였고 연산의 어려움을 해결하기 위해 곱과 분을 따로 하 기로 하였다 아래와 같은 소스를 완성하였다.( 추가 설명은 각주에서). #include <stdio.h> #include <stdlib.h> double sum[400]; //계산한값을 받을 더블형 배열 int size; //반복문에서 사용될 배열의 크기, 배열은 위의 크기로 선언되나 반복문에서는 필요한부분만 사용하여 연산 intm,n; //입력받을 값의 변수
  • 8. void Calculation(){ //답을 구하는 방법은 공식을 사용. 공식은 nCm = n!/m!/(n-m)! = (n*(n-1)*(n-2)*...*(n-m+1)/m! 이며 오른쪽 식을 사용하여 답을 구하도록했다. double a,b; //계산에필요한 변수 int c; //배열번호를 담당하는 변수 double buffer,temp; //연산에서 임시로 저장할 변수 int s=0; buffer=0; for(a=n-1,b=m-1;a>=(n-m+1)||b>0; ){ c=size-1; if(a>=(n-m+1)){ //공식의 분자부분. n*(n-1)*(n-2)*...*(n-m+1)를 수행한다 while(c>=0){ //sum[c]에 값을 곱했을때 값이 일정값을 넘으면 sum[c+1]에 넘치는 값을 넘기 도록 했다. sum[c]=sum[c]*a;//sum[0]은 기본적으로 1이다. 다른 값은 0이다. if(sum[size-1]!=0) //반복문을 돌리는 배열중 최상위 배열이 0이 아닐때 사용하는 배열을 늘린다. 기본적으로 sum[0]과 sum[1] 두개를 사용한다 size++; if(sum[c]>=1e+9){ //값이 9자리를 넘을때 넘치는 값을 나누어 다음 배열에 넘기는 부분이다. temp=(unsigned)(sum[c]/(1e+9)); sum[c+1]=sum[c+1]+temp; sum[c]=sum[c]-(temp*(1e+9)); } c--; } a--; } else if(b>0&&a==(n-m)){ //위의 분자부분 연산이 끝나면 분모부분의 연산을 수행한다. 여기서 는 매숫자마다값을 나누어주어 저장하는 식으로 진행한다. while(c>=0){if(sum[c]!=0&&s==0) //값이 존재하는 배열이 나올때까지 연산을 하지않기위해 이 구문을 넣었다. s=1; if(s==1){ //연산은 최상위 배열값부터 나누어 내려가며 나눈값소수점이하 부분에 1e+9(1000000000)를 곱하여 if(sum[c]/b>=1){ //buffer변수에 저장한다. temp=(sum[c]/b)+buffer; //배열에 buffer를 더하고(첫 buffer는 0이다.) 연산할 값을 나눈후임시값에 저장한다. sum[c]=(unsigned)temp; //나눈값은 소수점이 있을 수 있으므로 소수점이하는 버리고 정수부분만 저장시킨다.
  • 9. buffer=(temp-sum[c])*(1e+9); //버퍼에 배열을 나누값의 정수부분을 뺀 나머지 소수부분에 1e+9를 곱해준다. if(c==0){ //최하위 배열의 경우 연산후 다음 연산을 위해 버퍼에 0을 저장한다. buffer=0; s=0; } } else{ //배열값을나눴을때 1미만일 경우 배열에 0을 저장하고 나머지값은 buffer에 저장한다. buffer=sum[c]/b*(1e+9); sum[c]=0; } } if(sum[c]>=1e+9){ //만약 배열에 저장된값이 1e+9보다 클때 넘치는 값을 윗 배열로 넘긴다. temp=(unsigned)(sum[c]/(1e+9)); sum[c+1]=sum[c+1]+temp; sum[c]=sum[c]-(temp*(1e+9)); } c--; } b--; } } } void main(){ int x; int y=0; printf("열을 입력해주세요 : "); scanf("%d",&n); printf("행을 입력해주세요 : "); scanf("%d",&m); size=2; for( x=0 ; x<400 ; x++ ){ //값을 계산할 배열 값을 초기화. 첫번째 배열만 1로 선언하고 나머지는 모두 0으로 선언 if( x==0 ){ sum[x]=1; continue;
  • 10. } sum[x]=0; } Calculation(); //값을 구하기위한 계산함수 printf("%d번째 행의 %d번째 열의 숫자는 ",n,m); for( x=size-1 ; x>=0 ; x-- ){ //답을 출력하는 반복문. 계산과정에서 값을 저장하는 자료형의 크기의 한계를 극복하기위해 if(sum[x]!=0||y==1){ //일정 값을 넘어가면 넘치는 부분을 다음 배열에 저장하도록 하였기 때문에 결과값이 나누어져있어 if(y==0){ //한번에 출력할수없어 부득이 반복문을 사용하였다. printf("%.f",sum[x]); //배열이 0일때는 출력하지 않도록 했고 결과값이 나오면 그 밑의 값은 모두 출력하도록했다. y=1; continue; } printf("%09.f",sum[x]); } } printf("입니다.n"); _getch(); - 위 코드에는 치명적인 결함이 있다. 오차가 생기는 점이다. 그 이유는 값을 나누는 과정 에서 자료형의 소수점 정밀도 때문이다. 따라서 결과값의 정확한 자릿수 정도는 구할 수 있을지 모르나 정확한 결과 값을 기대하긴 어렵다. 단 50행 이하의 적은 숫자는 정확한 값을 구할 수 있다.3월 20일 최종 소스 작성 및 최종보고서 검토 - 배열크기가 불필요하게 커서 400 - >160 으로 축소 하였고, 연산 과정에서 오류가 발생해 서 최종 수정을 했다. (sum[0]가ㅏ 0이됬을 때 나눗셈 과정에서 숫자를 들여오지 못하는 오류)#include <stdio.h>#include <stdlib.h>double sum[160]; //계산한값을 받을 더블형 배열int size; //반복문에서 사용될 배열의 크기,배열은 위의 크기로 선언되나 반복문에서는필요한부분만 사용하여 연산intm,n; //입력받을 값의 변수void Calculation();
  • 11. void main(){int x;int y=0;printf("열을 입력해주세요 : ");scanf("%d",&n);printf("행을 입력해주세요 : ");scanf("%d",&m);size=2; for( x=0 ; x<160 ; x++ ){ //값을 계산할 배열 값을 초기화. 첫번째 배열만 if( x==0 ){//로 선언하고 나머지는 모두 0으로 선언 sum[x]=1;continue; }sum[x]=0; } Calculation(); //값을 구하기위한 계산함수printf("%d번째 행의 %d번째 열의 숫자는 ",n,m); for( x=size-1 ; x>=0 ; x-- ){ //답을 출력하는 반복문. 계산과정에서 값을 //저장하는 자료형의 크기의 한계를 극복하기위해if(sum[x]!=0||y==1){ //일정 값을 넘어가면 넘치는 부분을 다음 배열에 //저장하도록 하였기 때문에 결과값이 나누어져있어 if(y==0){ //한번에 출력할수없어 부득이 반복문을 사용하였다.printf("%.f",sum[x]); //배열이 0일때는 출력하지 않도록 했고 결과값이 //나오면 그 밑의 값은 모두 출력하도록했다. y=1;continue; }printf("%09.f",sum[x]); } }printf("입니다.n");getch(); //이 코드에는 치명적인 결함이 있는데 값을 나누는 과정에서 자료형의 소수점 정밀도에 의해 오차가 생긴다는 점이다. //따라서 결과값의 정확한 자릿수 정도는 구할 수 있을지 모르나 정확한 결과값을 기대하긴 어렵다 //다만 50행 이하의 적은 숫자는 정확한 값을 구할 수 있다.}void Calculation(){ //답을 구할때에는 공식을 사용했다. //공식은 aCb = a!/a!/(a-b)! = (a*(a-1)*(a-2)*...*(a-b+1)/b! 이다
  • 12. double a,b; //계산에필요한 변수int c; //배열번호를 담당하는 변수 double buffer,temp; //연산에서 임시로 저장할 변수int s=0;buffer=0;for(a=n-1,b=m-1;a>=(n-m+1)||b>0; ){ c=size-1; if(a>=(n-m+1)){ //공식의 분자부분. n*(n-1)*(n-2)*...*(n-m+1)를 수행한다 for(;c>=0;c--){ //sum[c]에 값을 곱했을때 값이 일정값을 넘으면 //sum[c+1]에 넘치는 값을 넘기도록 했다. sum[c]=sum[c]*a; //sum[0]은 기본적으로 1이다. 다른 값은 0이다. if(sum[c]>=1e+9){ //값이 9자리를 넘을때 넘치는 값을 나누어 다음 배열에 넘기는 부분이다.temp=(unsigned)(sum[c]/(1e+9));sum[c+1]=sum[c+1]+temp;sum[c]=sum[c]-(temp*(1e+9)); }if(sum[size-1]!=0) //반복문을 돌리는 배열중 최상위 배열이 0이 아닐때 사용하는 배열을 늘린다.size++; } a--; } else if(b>0&&a==(n-m)){ //위의 분자부분 연산이 끝나면 분모부분의 연산을 수행한다. //여기서는 매숫자마다 값을 나누어주어 저장하는 식으로 진행한다.for(;c>=0;c--){if(sum[c]!=0&&s==0) //값이 존재하는 배열이 나올때까지 연산을 하지않기위해 이 구문을 넣었다. s=1; if(s==1){ //연산은 최상위 배열값부터 나누어 내려가며 나눈값의 //수점이하 부분에 1e+9(1000000000)를 곱하여 if(sum[c]/b>=1){ //buffer변수에 저장한다. temp=(sum[c]/b)+buffer; //배열에 buffer를 더하고(첫 buffer는 0이다.) 연산할 값을 나눈후임시값에 저장한다. sum[c]=(unsigned)temp; //나눈값은 소수점이 있을 수 있으므로 소수점이하는 버리고 정수부분만 저장시킨다. buffer=(temp-sum[c])*(1e+9); //버퍼에 배열을 나누값의 정수부분을 뺀 나머지 소수부분에 1e+9를 곱해준다. }else if(sum[c]==0)sum[c]=buffer; else{ //배열값을나눴을때 1미만일 경우 배열에 0을 저장하고 나머지값은 buffer에 저
  • 13. 장한다.buffer=sum[c]/b*(1e+9);sum[c]=0; } }if(c==0){ buffer=0; //최하위 배열의 경우 연산후 다음 연산을 위해 버퍼에 0을 저장한다. s=0; } if(sum[c]>=1e+9){ //만약 배열에 저장된값이 1e+9보다 클때 넘치는 값을 윗 배열로 넘긴다.temp=(unsigned)(sum[c]/(1e+9));sum[c+1]=sum[c+1]+temp;sum[c]=sum[c]-(temp*(1e+9)); } }b--; } }}