• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
자료구조 Project1
 

자료구조 Project1

on

  • 287 views

 

Statistics

Views

Total Views
287
Views on SlideShare
287
Embed Views
0

Actions

Likes
0
Downloads
0
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft Word

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    자료구조 Project1 자료구조 Project1 Document Transcript

    • C1 조Project #1파스칼의 삼각형C12012-03-17
    • 목차1. 프로젝트 수행 결과 보고서 ............................................................................................................ 3프로젝트의 목적 ..................................................................................................................................... 3프로젝트의 내용 ..................................................................................................................................... 3프로젝트의 진행 방법 ............................................................................................................................ 3프로젝트 결과 ......................................................................................................................................... 3참고문헌 및 웹 ....................................................................................................................................... 32. 프로젝트 수행 일지 ........................................................................................................................... 43월 6일 프로젝트 착수 .......................................................................................................................... 43월 10일 일정계획 및 진행방법 토의 .................................................................................................. 53월 13일 업무 분담 및 1차 소스 작성 ................................................................................................ 53월 15일 2차 소스 작성 ........................................................................................................................ 63월 18일 소스 완료 및 최종보고서 작성 ............................................................................................. 73월 20일 최종 소스 작성 및 최종보고서 검토 .................................................................................. 10
    • 1. 프로젝트 수행 결과 보고서프로젝트의 목적 - 배열의 사용법을 안다. - 프로그램의 시간,공간 복잡도를 계산할 수 있다.프로젝트의 내용 - 배열을 이용하여 파스칼의 삼각형을 출력하는 프로그램을 작성하고, 시간 복잡도와 공간 복잡도를 이용하여 보다 빠르고 메모리 손실이 작은 프로그램을 만들자.프로젝트의 진행 방법 - 전체적인 프로젝트 진행은 팀원들과의 협동을 통해 진행되며 각자의 역할을 분담하여 프 로젝트 진행 속도와 완성도를 높이는 방향으로 진행된다.프로젝트 결과 - 50행 이하의 파스칼의 삼각형 출력에는 문제가 없으나 그 이상의 행에서는 소수점 이하 의 오차가 발생하는 프로그램이 완성되었다. - 최종 검토 과정에서 생각지 못한 오류와 불필요한 메모리 손실이 발견되어 재 수정을 거 쳤고 오차와 메모리손실을 줄였다.참고문헌 및 웹http://10albatross.tistory.com/27http://carstart.tistory.com/122http://skmagic.tistory.com/164
    • http://qwe1qwe.tistory.com/880C로 쓴 자료구조론_HOROWITZ,Sahni,Anderson-Freed저 , wikepedia.org , httpispkorea.com , 2. 프로젝트 수행 일지3월 6일 프로젝트 착수 - 조 편성 및 프로젝트 문제 인식 - 문제 인식 :배열을 이용하여 파스칼의 삼각형을 문제에서 요구하는 대로 출력 해야한다. 사실상 파스칼의 삼각형 출력은 어려운 것이 아니다. 하지만, 자료형 제한과 메모리와 시간의 균형을 맞추는 것이 매우 어려울 것이다. - 파스칼의 삼각형이란?
    • 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이기 때문에 , 걸러준다.
    • { 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 을 대입받는다.
    • 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; //입력받을 값의 변수
    • 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; //나눈값은 소수점이 있을 수 있으므로 소수점이하는 버리고 정수부분만 저장시킨다.
    • 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;
    • } 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();
    • 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! 이다
    • 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에 저
    • 장한다.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--; } }}