21
자료구조 A1조 과제 보고서 [Project #3:다항식 계산] 조장 : 김선형 조원 : 정의수 전승협

2012 Ds A1 03

Embed Size (px)

Citation preview

Page 1: 2012 Ds A1 03

자료구조 A1조

과제 보고서[Project #3:다항식 계산]

조장 : 김선형

조원 : 정의수

전승협

Page 2: 2012 Ds A1 03

과제수행일지소속 조원

A1 조장 : 김선형 자료조사 : 김선형 프로그래밍 : 정의수, 전승협과제수행기간 5일 약 20시간

I. 계획의 작성

연구제목 다항식의 연산

연구배경linked list의 구조와 사용 방법을 알고 다항식 연산 과제를 수행하면서 list에 대하여 이해한다.

참고자료

참고 서적C로 쓴 자료구조론/HOROWITZ, Sahni, Anderson-Freed 저/이석호 역/ 교보문고

참고 URL

-dblab.duksung.ac.kr/ds/pdf/Chap06.pdf 연결 리스트의 개념과 구현하는 방법 및 다항식 계산에 관한 참고 자료-http://croute.me/27

II. 계획의 실행

첫째 날 2012년 4월 12일 목요일오늘의 작업 조원의 업무 분담 및 과제에 대한 이해와 숙지

토의 내용

조장 : 김선형자료조사 : 김선형프로그래밍 : 정의수, 전승협

본래 구성된 조원은 4명이었으나 그 중 한 명이 수업에 참여를 하지 않는 관계로 인원이 3명이 되었다. 업무분담을 한 명씩 하기에는 각자 부담이 많아질 것 같아 위와 같이 업무 분담을 하게 되었다.

과제준비에서

느낀 점

수업이나 토의에 참여하지 않는 조원이 한 명이라도 있을 경우에는 그만큼 다른 조원에게 피해가 생기고 과제 수행에 대한 부담이 좀 더 가중된다는 것을 알게 되었다.

Page 3: 2012 Ds A1 03

둘째 날 2012년 4월 17일 화요일오늘의 작업 linked list에 대한 이해와 숙지

토의 내용

과제 수행을 하기 위해 우선적으로 필요한 linked list에 대한 내용에 대해 토의를 하였다. 연결 리스트는 각 노드가 데이터와 포인터를 가지고 한 줄로 연결되어 있는 방식으로 데이터를 저장하는 자료 구조이다. 이름에서 말하듯이 데이터를 담고 있는 노드들이 연결되어 있는데, 노드의 포인터가 다음이나 이전의 노드와의 연결을 담당하게 된다. 연결 리스트는 늘어선 노드의 중간지점에서도 자료의 추가와 삭제가 O(1)의 시간에 가능하다는 장점을 갖는다. 그러나 배열이나 트리 구조와는 달리 특정 위치의 데이터를 검색해 내는 데에는 O(n)의 시간이 걸리는 단점도 갖고 있다.

<그림1.생성된 리스트 노드의 형태>연결 리스트에는 3가지의 종류가 있다. 하나는 가장 기본적인 연결 리스트로 위에서 설명된 내용이다. 첫 번째 노드가 그다음 노드를 또 그다음 노드를 순차적으로 연결하는 구조(그림1)이다.두 번째는 원형 연결 리스트로 단순 연결 리스트와는 차이점이 하나 밖에 없다. Head는 처음에 존재하지만, 마지막 노드가 제일 처음의 노드를 다시 가리키게 하는 것이다.

<그림2.원형 연결 리스트>세 번째는 이중 연결 리스트로, 앞뒤 움직임이 자유롭다. 즉, 자료가 1→2→3→4... 의 순차적인 방향으로 연결될 수도 있지만 4→3→2→1... 의 역순으로도 연결될 수 있다는 것을 의미한다. (여기서는 Head와 Tail 부분이 NULL인데 이 두개를 연결시키기도 한다.)

<그림3.이중 연결 리스트>위와 같이 조사한 내용을 바탕으로 리스트의 구조에 대해 이해하고 과제 진행을 위한 알고리즘을 구성하기로 하였다.

과제준비에서

느낀 점

다른 조보다 조원이 적은 상황이었지만 조원들 모두가 적극적인 자세로 임하여 자료를 조사해 오고 과제를 수행해 나가려고 하였다.

Page 4: 2012 Ds A1 03

셋째 날 2012년 4월 18일 수요일오늘의 작업 다항식 계산 코딩 과제를 수행하기 위한 기초 알고리즘 구성

토의 내용

다항식 계산 코딩 과제를 위해 필요한 알고리즘에 대해 토의를 하였다.입력방식은 파일을 받는 게 아니라 직접 키보드로 입력을 받는 방법을 선택하였다. 입력 부분과 노드에 저장할 내용들을 따로 함수로 구성하기로 하였고 마찬가지로 덧셈, 뺄셈, 곱셈에 대한 계산도 함수로 구현하기로 정했다.나눗셈 계산에 관해서는 확실한 알고리즘이 짜여 지지 않아 우선 다른 함수들을 구현하면서 알고리즘을 구성해보기로 하였다.

덧셈계산 함수는 교재에 있는 덧셈계산 내용을 참고하였고, 뺄셈계산 함수는 덧셈계산 함수에서 조금의 수정을 하는 것으로 구현하기로 하였다. 곱셈계산 함수는 P(x)의 최고차항의 수를 S(x)에 전부 곱해주고 정열해주는 방법을 사용하기로 하였다.

과제준비에서

느낀 점

조원 모두가 자기가 생각하는 의견을 말하고 그 의견들을 종합해서 결과를 내놓는 것이 혼자서 과제를 수행하는 것보다 훨씬 수월함을 알게 되었다. 이번 과제의 경우 사용할 수 있는 리스트의 종류도 많고 이해할 내용도 많았는데 조원 모두 적극적인 자세로 임해서 과제 수행에 있어 진행도가 한결 빨라진 것 같다.

넷째 날 2012년 4월 19일 목요일오늘의 작업 다항식 계산 과제의 프로그램 소스 초안 코딩

토의 내용

소스 초안

기존 알고리즘에서 입력된 값을 다항식의 형태로 출력해주는 함수를 추가로 구현하기로 하였다. 아래 내용은 구성한 알고리즘을 토대로 구현한 코딩 과제 소스의 초안이다.

#include <stdio.h> //main함수 사용 헤더

#include <stdlib.h> //malloc 사용 헤더

#include <conio.h> //getch() 사용 때문에 추가한 헤더. 리눅스에서 컴파일 할 때는 필요없다

typedef struct list_node * list_ptr;

typedef struct list_node {

int coef; //계수

int expon; //차수

list_ptr *link;

}list_node;

//리스트를 만들기 위한 구조체 선언

list_ptr input(); //입력받는 함수

list_ptr add_last(list_ptr L, int c, int e); //입력받은 다항식을 리스트에 저장하는 함수

list_ptr pAdd(list_ptr Px, list_ptr Sx); //덧셈연산을 하는 함수

list_ptr pSubt(list_ptr Px, list_ptr Sx); //뺄셈연산을 하는 함수

list_ptr pMult(list_ptr Px, list_ptr Sx); //곱셈연산을 하는 함수

list_ptr pDiv(list_ptr Px, list_ptr Sx); // 나눗셈연산을 하는 함수

void print(list_ptr p); //리스트에 저장된 다항식을 'P(x)='의 형태로 출력하는 함수

list_ptr save(list_ptr p, int c, int e, list_ptr *sol); //연산한 결과를 리스트에 저장하는 함수

Page 5: 2012 Ds A1 03

list_ptr input(){

list_ptr s = NULL;

int c, e;

for( ; c != 0 || e != 0; ){

printf("계수, 차수 입력(종료는 0,0입력) : ");

scanf("%d %d", &c, &e);

if(c != 0) s = add_last(s, c, e);}

return s;

} //입력부. 입력받은 다항식을 void print(p)함수로 return

list_ptr add_last(list_ptr L, int c, int e){

list_ptr newNode, n; //저장받을 Node 생성

newNode = (list_ptr*)malloc(sizeof (struct list_node)); //newNode 동적할당

newNode->coef = c; //구조체 내부의 변수 coef를 c에 저장

newNode->expon = e; //구조체 내부의 변수 expon를 e에 저장

newNode->link = NULL;

if (L == NULL) {

L = newNode;

return L;}

n = L;

for ( ; n->link != NULL ; ) n = n->link;

n->link = newNode;

return L;

}

void print(list_ptr p){

for( ; p != NULL ; ) {

printf("%dx^%d", p->coef, p->expon);

p = p->link;

if (p != NULL && p->coef > 0) printf("+");}

printf("\n");

}

list_ptr save(list_ptr p, int c, int e, list_ptr *sol){

list_ptr newNode; //저장받을 Node 생성

newNode = (list_ptr*)malloc(sizeof (struct list_node)); //newNode 동적할당

newNode->coef = c; //구조체 내부의 변수 coef를 c에 저장

newNode->expon = e; //구조체 내부의 변수 expon를 e에 저장

if ( p == NULL ) {

p = newNode;

*sol = newNode; }

else {

(*sol)->link = newNode;

*sol = newNode;}

(*sol)->link = NULL;

return p;

}

Page 6: 2012 Ds A1 03

list_ptr pAdd(list_ptr Px, list_ptr Sx){ //덧셈

list_ptr a,b,c,d;

int sum;

a=Px;

b=Sx;

c=NULL;

d=NULL;

for( ; a != NULL && b != NULL ; ){

if(a->expon < b->expon){ //a의 expon이 b의 expon보다 작은 경우

c=save(c, b->coef, b->expon, &d);

b=b->link;}

else if(a->expon == b->expon){ //a의 expon이 b의 expon과 같을 경우

sum=a->coef+b->coef;

if(sum != 0) c=save(c, sum, a->expon, &d);

a=a->link;

b=b->link;}

else if(a->expon > b->expon){ //a의 expon이 b의 expon보다 큰 경우

c=save(c, a->coef, a->expon, &d);

a=a->link;}

}

for( ; a != NULL ; ){

c= save(c, a->coef, a->expon, &d);

a= a->link; }

for( ; b != NULL ; ){

c=save(c, b->coef, b->expon, &d);

b= b->link;}

d->link = NULL;

return c;

}

list_ptr pSubt(list_ptr Px, list_ptr Sx){ //뺄셈

list_ptr a,b,c,d;

int sum;

a=Px;

b=Sx;

c=NULL;

d=NULL;

for( ; a != NULL && b != NULL ; ){

b->coef=b->coef*(-1); //S(x)의 다항식의 계수에 -1을 곱해줘서 뺄셈 연산을 함

if(a->expon < b->expon){ //a의 expon이 b의 expon보다 작은 경우

c=save(c, b->coef, b->expon, &d);

b=b->link;}

else if(a->expon == b->expon){ //a의 expon이 b의 expon과 같을 경우

sum=a->coef+b->coef;

if(sum != 0) c=save(c, sum, a->expon, &d);

a=a->link;

b=b->link;}

Page 7: 2012 Ds A1 03

else if(a->expon > b->expon){ //a의 expon이 b의 expon보다 큰 경우

c=save(c, a->coef, a->expon, &d);

a=a->link;}

}

for( ; a != NULL ; ){

c= save(c, a->coef, a->expon, &d);

a= a->link; }

for( ; b != NULL ; ){

c=save(c, b->coef, b->expon, &d);

b= b->link;}

d->link = NULL;

return c;

}

list_ptr pMult(list_ptr Px, list_ptr Sx){ //곱셈

list_ptr a,b,c,d, result;

b=Sx; //S(x) 다항식을 변수 b에 저장

c=NULL; //결과 다항식 저장. 최초값은 NULL

for( ; b != NULL; ){

a=Px;

d=NULL;

result=NULL; //임시 저장할 Node. 최초값은 NULL

for( ; a != NULL ; ){

result=save(result, a->coef*b->coef, a->expon+b->expon, &d); //계수

는 곱해주고 차수는 더해준 값을 save함수의 노드에 저장

a=a->link;}

c=pAdd(result,c); //차수 순으로 정렬하기 위해 연산

b=b->link;

}

return c;

}

void main(){

list_ptr Px, Sx, Tx;

printf("P(x) 입력\n");

Px= input(); //입력 함수 호출

printf("S(x) 입력\n");

Sx= input(); //입력 함수 호출

printf("\n");

printf("P(x) = ");

print(Px); //P(x) 다항식 호출

printf("S(x) = ");

print(Sx); //S(x) 다항식 호출

printf("덧셈 연산 : ");

Tx=pAdd(Px,Sx);

printf("T(x) = ");

Page 8: 2012 Ds A1 03

print(Tx);

printf("뺄셈 연산 : ");

Tx=pSubt(Px,Sx);

printf("T(x) = ");

print(Tx);

/*for( ; add_last->link=NULL; link++){

free(add_last->link);}

free(add_last);*/

printf("곱셈 연산 : ");

Tx=pMult(Px,Sx);

printf("T(x) = ");

print(Tx);

printf("\n");

printf("종료하려면 엔터를 치시오");

getch();

return 0;

}

문제점

덧셈 계산과 곱셈 계산은 구현을 했지만 나눗셈 계산은 알고리즘을 완벽하게 구성하지 못해서 구현을 하지 못하였다. 뺄셈 계산은 함수 첫줄에서 S(x)의 계수에 -1을 곱해주는 식으로 계산을 하였지만 그렇게 구현을 하니 계산된 값이 원하던 값과는 다른 형태로 나오는 경우가 발견되었다. 또 동적할당을 해제하는 것을 메인 함수 내에서 구현을 해보려 하였지만 오류가 났다.

해결 방안

뺄셈 계산은 함수 첫줄에서 S(x)의 계수에 -1을 곱해주는 것이 아니라 P(x)와 S(x)의 차수가 같을 때 빼주고 P(x)의 차수가 높으면 P(x)를 그대로 내보내고 S(x)의 차수가 크면 그 계수에 -를 붙여서 내보내는 식으로 해결을 했다. 동적할당 해제는 whlie문을 사용해서 따로 함수를 만들어 마지막에 함수 호출을 하는 식으로 해결하였다.

다섯째 날 2012년 4월 21일 토요일오늘의 작업 다항식 계산 과제의 프로그램 소스 2안 코딩

토의 내용

소스 2안

구성하지 못했던 나눗셈 알고리즘을 구성하기 위해 토의를 하였다. 우선 다항식의 나눗셈을 할 때 P(x)의 최고차수의 값을 S(x)의 최고차수의 값으로 나누고 나눈 값을 S(x) 전체에 곱해준 다음 그 결과 값을 P(x)에서 빼주는 것으로 Q(x)와 R(x)를 구현하기로 하였다. 아래는 위의 알고리즘 내용을 바탕으로 구현한 2안 소스이다.

#include <stdio.h> //main함수 사용 헤더

#include <stdlib.h> //malloc 사용 헤더

#include <conio.h> //getch() 사용 때문에 추가한 헤더. 리눅스에서 컴파일 할 때는 필요없다

typedef struct list_node * list_ptr;

Page 9: 2012 Ds A1 03

typedef struct list_node {

int coef; //계수

int expon; //차수

list_ptr *link;

};

//리스트를 만들기 위한 구조체 선언

list_ptr input(); //입력받는 함수

list_ptr add_last(list_ptr L, int c, int e); //입력받은 다항식을 리스트에 저장하는 함수

list_ptr pAdd(list_ptr Px, list_ptr Sx); //덧셈연산을 하는 함수

list_ptr pSubt(list_ptr Px, list_ptr Sx); //뺄셈연산을 하는 함수

list_ptr pMult(list_ptr Px, list_ptr Sx); //곱셈연산을 하는 함수

list_ptr pDiv(list_ptr Px, list_ptr Sx); // 나눗셈연산을 하는 함수

void print(list_ptr p); //리스트에 저장된 다항식을 'P(x)='의 형태로 출력하는 함수

list_ptr save(list_ptr p, int c, int e, list_ptr *sol); //연산한 결과를 리스트에 저장하는 함수

void pree(list_ptr p); //할당받은 메모리를 해제해주는 함수

list_ptr input(){

list_ptr s = NULL;

int c, e;

for( ; c != 0 || e != 0; ){

printf("계수, 차수 입력(종료는 0,0입력) : ");

scanf("%d %d", &c, &e);

if(c != 0) s = add_last(s, c, e);}

return s;

} //입력부. 입력받은 다항식을 void print(p)함수로 return

list_ptr add_last(list_ptr L, int c, int e){

list_ptr newNode, n; //저장받을 Node 생성

newNode = (list_ptr*)malloc(sizeof (struct list_node)); //newNode 동적할당

newNode->coef = c; //구조체 내부의 변수 coef를 c에 저장

newNode->expon = e; //구조체 내부의 변수 expon를 e에 저장

newNode->link = NULL;

if (L == NULL) {

L = newNode;

return L;}

n = L;

for ( ; n->link != NULL ; ) n = n->link;

n->link = newNode;

return L;

}

void print(list_ptr p){

for( ; p != NULL ; ) {

printf("%dx^%d", p->coef, p->expon);

Page 10: 2012 Ds A1 03

p = p->link;

if (p != NULL && p->coef > 0) printf("+");}

printf("\n");

}

list_ptr save(list_ptr p, int c, int e, list_ptr *sol){

list_ptr newNode; //저장받을 Node 생성

newNode = (list_ptr*)malloc(sizeof (struct list_node)); //newNode 동적할당

newNode->coef = c; //구조체 내부의 변수 coef를 c에 저장

newNode->expon = e; //구조체 내부의 변수 expon를 e에 저장

if ( p == NULL ) {

p = newNode;

*sol = newNode; }

else {

(*sol)->link = newNode;

*sol = newNode;}

(*sol)->link = NULL;

return p;

}

list_ptr pAdd(list_ptr Px, list_ptr Sx){ //덧셈

list_ptr a,b,c,d;

int sum;

a=Px;

b=Sx;

c=NULL;

d=NULL;

for( ; a != NULL && b != NULL ; ){

if(a->expon < b->expon){ //a의 expon이 b의 expon보다 작은 경우

c=save(c, b->coef, b->expon, &d);

b=b->link;}

else if(a->expon == b->expon){ //a의 expon이 b의 expon과 같을 경우

sum=a->coef+b->coef;

if(sum != 0) c=save(c, sum, a->expon, &d);

a=a->link;

b=b->link;}

else if(a->expon > b->expon){ //a의 expon이 b의 expon보다 큰 경우

c=save(c, a->coef, a->expon, &d);

a=a->link;}

}

for( ; a != NULL ; ){

c= save(c, a->coef, a->expon, &d);

a= a->link; }

for( ; b != NULL ; ){

Page 11: 2012 Ds A1 03

c=save(c, b->coef, b->expon, &d);

b= b->link;}

d->link = NULL;

return c;

}

list_ptr pSubt(list_ptr Px, list_ptr Sx){ //뺄셈

list_ptr a,b,c,d;

int sum;

a=Px;

b=Sx;

c=NULL;

d=NULL;

for( ; a != NULL && b != NULL ; ){

if(a->expon < b->expon){ //a의 expon이 b의 expon보다 작은 경우

c=save(c, -b->coef, b->expon, &d);

b=b->link;}

else if(a->expon == b->expon){ //a의 expon이 b의 expon과 같을 경우

sum=a->coef-b->coef;

if(sum != 0) c=save(c, sum, a->expon, &d);

a=a->link;

b=b->link;}

else if(a->expon > b->expon){ //a의 expon이 b의 expon보다 큰 경우

c=save(c, a->coef, a->expon, &d);

a=a->link;}

}

for( ; a != NULL ; ){

c= save(c, a->coef, a->expon, &d);

a= a->link; }

for( ; b != NULL ; ){

c=save(c, -b->coef, b->expon, &d);

b= b->link;}

d->link = NULL;

return c;

}

list_ptr pMult(list_ptr Px, list_ptr Sx){ //곱셈

list_ptr a,b,c,d, result;

b=Sx; //S(x) 다항식을 변수 b에 저장

c=NULL; //결과 다항식 저장. 최초값은 NULL

for( ; b != NULL; ){

a=Px;

d=NULL;

result=NULL; //임시 저장할 Node. 최초값은 NULL

Page 12: 2012 Ds A1 03

for( ; a != NULL ; ){

result=save(result, a->coef*b->coef, a->expon+b->expon, &d); //계수

는 곱해주고 차수는 더해준 값을 save함수의 노드에 저장

a=a->link;}

c=pAdd(result,c); //차수 순으로 정렬하기 위해 연산

b=b->link;

}

return c;

}

list_ptr pDiv(list_ptr Px, list_ptr Sx){

list_ptr a,b,c,d,result;

list_ptr temp1, temp2;

a=Px;

b=Sx; //S(x) 다항식을 변수 b에 저장

c=NULL;

if(a!=NULL && b!=NULL){

if(a->expon>=b->expon){

result=NULL;

d=NULL;

result=save(result, a->coef/b->coef, a->expon-(b->expon), &d);

}

temp1=pMult(result,b);

temp2=pSubt(a, temp1);

d=d->link;}

while(1){

if(temp2->expon>=b->expon){

result=save(result, temp2->coef/b->coef, temp2->expon-(b->expon),

&d);

temp1=pMult(result,b);

c=pSubt(a, temp1);

d=d->link;}

else if(temp2->expon<b->expon){

c=temp2;

break;}

}

return c;

}

Page 13: 2012 Ds A1 03

void pree(list_ptr p){

list_ptr temp;

while(p){

temp=p;

p=p->link;

free(temp);}

}

void main(){

list_ptr Px, Sx, Tx;

printf("P(x) 입력\n");

Px= input(); //입력 함수 호출

printf("S(x) 입력\n");

Sx= input(); //입력 함수 호출

printf("\n");

printf("P(x) = ");

print(Px); //P(x) 다항식 호출

printf("S(x) = ");

print(Sx); //S(x) 다항식 호출

printf("덧셈 연산 : ");

Tx=pAdd(Px,Sx);

printf("T(x) = ");

print(Tx);

pree(Tx);

printf("뺄셈 연산 : ");

Tx=pSubt(Px,Sx);

printf("T(x) = ");

print(Tx);

pree(Tx);

printf("곱셈 연산 : ");

Tx=pMult(Px,Sx);

printf("T(x) = ");

print(Tx);

pree(Tx);

printf("나눗셈 연산 : ");

Tx=pDiv(Px, Sx);

printf("P(x) = S(x)*Q(x)+R(x)\n");

//printf("Q(x) = ");

printf("R(x) = ");

print(Tx);

pree(Tx);

Page 14: 2012 Ds A1 03

printf("\n");

printf("종료하려면 엔터를 치시오");

getch();

return 0;

}

문제점

나눗셈 알고리즘을 완성해서 하나의 함수에서 Q(x)와 R(x)를 구해보려고 하였으나 반복문이 제대로 기능을 하지 못하고 오류가 나는 점을 발견하였다. 또 Q(x)와 R(x)의 값을 한꺼번에 리턴을 할 수가 없다는 점을 알았다.

해결 방안

나눗셈 계산을 하는 함수를 몫을 구하는 함수와 나머지를 구하는 함수를 따로 만들어 리턴을 해서 Q(x)와 R(x)의 값을 받는 방법을 사용하기로 하였다. 그리고 P(a)에 대해 a값을 돌려받는 함수를 따로 만들어 구현하기로 하였다.

III. 결과

최종 프로그램

소스

#include <stdio.h> //main함수 사용 헤더

#include <stdlib.h> //malloc 사용 헤더

typedef struct list_node * list_ptr;

typedef struct list_node {

int coef; //계수

int expon; //차수

list_ptr *link;

};

list_ptr input(); //입력받는 함수

list_ptr add_last(list_ptr L, int c, int e); //입력받은 다항식을 리스트에 저장하는 함수

list_ptr pAdd(list_ptr Px, list_ptr Sx); //덧셈연산을 하는 함수

list_ptr pSubt(list_ptr Px, list_ptr Sx); //뺄셈연산을 하는 함수

list_ptr pMult(list_ptr Px, list_ptr Sx); //곱셈연산을 하는 함수

list_ptr pDquo(list_ptr Px, list_ptr Sx); // 나눗셈연산 후 몫을 구하는 함수

list_ptr pDrem(list_ptr Px, list_ptr Sx); // 나눗셈연산 후 나머지를 구하는 함수

void print(list_ptr p); //리스트에 저장된 다항식을 'P(x)='의 형태로 출력하는 함수

list_ptr save(list_ptr p, int c, int e, list_ptr *sol); //연산한 결과를 리스트에 저장하는 함수

void pree(list_ptr p); //할당받은 메모리를 해제해주는 함수

list_ptr Sa(list_ptr px); // a를 입력받아서 계산하는 함수

list_ptr input(){

list_ptr s = NULL;

int c=-1, e=-1;

Page 15: 2012 Ds A1 03

for( ; c != 0 || e != 0; ){

printf("계수, 차수 입력(종료는 0,0입력) : ");

scanf("%d %d", &c, &e);

if(c != 0) s = add_last(s, c, e);}

return s;

} //입력부. 입력받은 다항식을 void print(p)함수로 return

list_ptr add_last(list_ptr L, int c, int e){

list_ptr newNode, n; //저장받을 Node 생성

newNode = (list_ptr*)malloc(sizeof (struct list_node)); //newNode 동적할당

newNode->coef = c; //구조체 내부의 변수 coef를 c에 저장

newNode->expon = e; //구조체 내부의 변수 expon를 e에 저장

newNode->link = NULL;

if (L == NULL) {

L = newNode;

return L;}

n = L;

for ( ; n->link != NULL ; ) n = n->link;

n->link = newNode;

return L;

}

void print(list_ptr p){

for( ; p != NULL ; ) {

printf("%dx^%d", p->coef, p->expon);

p = p->link;

if (p != NULL && p->coef > 0) printf("+");}

printf("\n");

}

list_ptr save(list_ptr p, int c, int e, list_ptr *sol){

list_ptr newNode; //저장받을 Node 생성

newNode = (list_ptr*)malloc(sizeof (struct list_node)); //newNode 동적할당

newNode->coef = c; //구조체 내부의 변수 coef를 c에 저장

newNode->expon = e; //구조체 내부의 변수 expon를 e에 저장

if ( p == NULL ) {

p = newNode;

*sol = newNode; }

else {

(*sol)->link = newNode;

*sol = newNode;}

(*sol)->link = NULL;

return p;

Page 16: 2012 Ds A1 03

}

list_ptr pAdd(list_ptr Px, list_ptr Sx){ //덧셈

list_ptr a,b,c,d;

int sum;

a=Px;

b=Sx;

c=NULL;

d=NULL;

for( ; a != NULL && b != NULL ; ){

if(a->expon < b->expon){ //a의 expon이 b의 expon보다 작은 경우

c=save(c, b->coef, b->expon, &d);

b=b->link;}

else if(a->expon == b->expon){ //a의 expon이 b의 expon과 같을 경우

sum=a->coef+b->coef;

if(sum != 0) c=save(c, sum, a->expon, &d);

a=a->link;

b=b->link;}

else if(a->expon > b->expon){ //a의 expon이 b의 expon보다 큰 경우

c=save(c, a->coef, a->expon, &d);

a=a->link;}

}

for( ; a != NULL ; ){

c= save(c, a->coef, a->expon, &d);

a= a->link; }

for( ; b != NULL ; ){

c=save(c, b->coef, b->expon, &d);

b= b->link;}

if ( d != NULL ) d->link = NULL;

return c;

}

list_ptr pSubt(list_ptr Px, list_ptr Sx){ //뺄셈

list_ptr a,b,c,d;

int sum;

a=Px;

b=Sx;

c=NULL;

d=NULL;

for( ; a != NULL && b != NULL ; ){

if(a->expon < b->expon){ //a의 expon이 b의 expon보다 작은 경우

c=save(c, -b->coef, b->expon, &d);

b=b->link;}

else if(a->expon == b->expon){ //a의 expon이 b의 expon과 같을 경우

sum=a->coef-b->coef;

if(sum != 0) c=save(c, sum, a->expon, &d);

Page 17: 2012 Ds A1 03

a=a->link;

b=b->link;}

else if(a->expon > b->expon){ //a의 expon이 b의 expon보다 큰 경우

c=save(c, a->coef, a->expon, &d);

a=a->link;}

}

for( ; a != NULL ; ){

c= save(c, a->coef, a->expon, &d);

a= a->link; }

for( ; b != NULL ; ){

c=save(c, -b->coef, b->expon, &d);

b= b->link;}

if ( d != NULL ) d->link = NULL;

return c;

}

list_ptr pMult(list_ptr Px, list_ptr Sx){ //곱셈

list_ptr a,b,c,d, result;

b=Sx; //S(x) 다항식을 변수 b에 저장

c=NULL; //결과 다항식 저장. 최초값은 NULL

for( ; b != NULL; ){

a=Px;

d=NULL;

result=NULL; //임시 저장할 Node. 최초값은 NULL

for( ; a != NULL ; ){

result=save(result, a->coef*b->coef, a->expon+b->expon, &d); //계수

는 곱해주고 차수는 더해준 값을 save함수의 노드에 저장

a=a->link;}

c=pAdd(result,c); //차수 순으로 정렬하기 위해 연산

b=b->link;

}

return c;

}

list_ptr pDrem(list_ptr Px, list_ptr Sx){ //나눗셈 나머지

list_ptr a,b,c,d,result;

list_ptr temp1=NULL;

a=Px;

b=Sx; //S(x) 다항식을 변수 b에 저장

c=NULL;

while(1){

if(a->expon>=b->expon){

result = NULL;

d=NULL;

Page 18: 2012 Ds A1 03

r e s u l t = s a v e ( r e s u l t , a - > c o e f / b - > c o e f ,

a->expon-(b->expon), &d);

temp1=pMult(result,b);

c=pSubt(a, temp1);

d=d->link;

a = c;

}

else if(a->expon<b->expon) break;

}

return c;

}

list_ptr pDquo(list_ptr Px, list_ptr Sx){ //나눗셈 몫

list_ptr a,b,c,d,result;

list_ptr temp1, temp2=NULL;

a=Px;

b=Sx;

c=NULL;

while(1){

if(a->expon>=b->expon){

result = NULL;

d=NULL;

result=save(result, a->coef/b->coef,

a->expon-(b->expon), &d);

temp2 = add_last(temp2, result->coef,

result->expon); //몫의 값을 노드에 저장

temp1=pMult(result,b);

c=pSubt(a, temp1);

d=d->link;

a = c;

}

else if(a->expon<b->expon) break;

}

return temp2;

}

void pree(list_ptr p){ //할당받은 메모리 해제

list_ptr temp;

while(p){

temp=p;

p=p->link;

free(temp);

}

Page 19: 2012 Ds A1 03

}

list_ptr Sa(list_ptr Px){ //a를 입력받아 P(a) 계산

int a,b,c,i,sum=0;

list_ptr p;

p=Px;

printf("P(a)를 입력 : ");

scanf("%d", &a);

for( ; p!=NULL; ){

b=1;

if(p->expon>0){

for(i=1; i<=p->expon; i++){

b*=a; //입력한 a에 대한 차수 곱

}

c=p->coef*b; //차수 곱에 계수를 곱해서 c에 저장

sum+=c; //결과값 sum에 c의 값을 누적

p=p->link; //다음 노드를 읽음

}else if(p->expon==0){ //차수가 0이면 sum값에 상수를 더해주고 반복문 탈출

sum=sum+p->coef;

break;

}

}

return sum;

}

void main(){

list_ptr Px, Sx, Tx;

printf("P(x) 입력\n");

Px= input(); //입력 함수 호출

printf("S(x) 입력\n");

Sx= input(); //입력 함수 호출

printf("\n");

printf("P(x) = ");

print(Px); //P(x) 다항식 호출

printf("S(x) = ");

print(Sx); //S(x) 다항식 호출

printf("\n");

printf("덧셈 연산 : ");

Tx=pAdd(Px,Sx);

printf("T(x) = ");

print(Tx);

Page 20: 2012 Ds A1 03

printf("뺄셈 연산 : ");

Tx=pSubt(Px,Sx);

printf("T(x) = ");

print(Tx);

printf("곱셈 연산 : ");

Tx=pMult(Px,Sx);

printf("T(x) = ");

print(Tx);

printf("나눗셈 연산 : \n");

printf("P(x) = S(x)*Q(x)+R(x)\n");

Tx=pDrem(Px,Sx);

printf("R(x) = ");

print(Tx);

Tx=pDquo(Px,Sx);

printf("Q(x) = ");

print(Tx);

pree(Tx);

printf("\n");

printf("<P(a) 계산>\n");

Tx=Sa(Px);

printf("P(a) = ");

printf("%d", Tx);

printf("\n");

return 0;

}

Page 21: 2012 Ds A1 03

결과 출력

시간복잡도

덧셈연산: O(n)뺄셈연산: O(n)곱셈연산: O(n²)나눗셈연산: O(n)임의의 a값에 대한 p(a)연산: O(n²)

공간복잡도 3n

Ⅳ. 반성

과제를 마치면서

느낀 점

다항식 계산 코딩 과제를 수행해 나가면서 구조체와 동적 할당 그리고 linked list에 대한 개념을 좀 더 확실하게 알게 되었다. 그리고 조원이 조사해 온 자료를 통해 linked list의 활용법과 종료 등의 개념을 이해할 수가 있었다. 단지 아쉬운 점은 중간고사 시험시간이 겹쳐서 조원들 모두가 여유가 없어 4월 24일에 완성을 하지 못했던 점이다.

기타

조원이 토의에 한 번도 참여를 하지 않은 적은 이번이 처음이었기 때문에 많이 당황스러웠다. 적은 인원으로 똑같은 팀 프로젝트를 수행해 나가려니 개인의 부담이 다른 때보다 많이 커지는 것을 느꼈다. 다음 팀 구성부터는 교수님께서 적절하게 구성해 주셨으면 하는 바람이 있다.