14
과과과과과과 과 과 B2 과과과과 조조 조조조 조조조조 조조조 조조조 조조조 조조조조조 조조조 과과과과 과과 3조 6 조조 과 과 과과과과 조조 조조 과 과 과 과 과과 URL ※ 조조 : 조조조 조조조 http://kin.naver.com/qna/detail.nhn? d1id=1&dirId=1040101&docId=64601805&qb=aW5maXggcG9zdGZpeCDrsJTqvrjripQ g67Cp67KV&enc=utf8&section=kin&rank=4&search_sort=0&spq=0 ※ 조조 : 조조조 조조조 (http://cafe.naver.com/clickhdwork.cafe?iframe_url=/ArticleRead.nhn %3Farticleid=709 &) 과과과 과과 과과과 2012조 3조 27조 조조조 과과 과과 조조 조조조조 조 조조조조, 조조 조조 과과 과과 ※조조 조조조 조조 조조 조조 조조조조조 조조 조조조조조 조조조조 조조조 조조조조 조조조조. 조조조 조조조 조조조조 조조, 조, 조조조조, infix expression, postfix expression 조 조조 조조조 조조조조조조 조조조 조조조조조조 조조조조조조 조조조 조조조 조조조 조조조조 조조조조 조조조조조조 조조조조조조 조조 조조조조조 조조조 조조조조 조조조조 조조조조조. 조조조 조조 조조조 조조 조조조조조 조조조 조조조조 조조조조 조조조 조조조 조조 조조조조조 조조조조조. 조조조 조조 : 조조조 조조조조조 : 조조조 조조조조 : 조조조, 조조조, 조조조 과과과 - 조조조 조조 조조조조 조조 과과 조조조 조조 조조조조조 조조조 조조조 조조 조조조 조조 조조조조조 조조 조조조 조조조조 조조조조조조.

자료구조 Project2

Embed Size (px)

Citation preview

Page 1: 자료구조 Project2

과제수행일지소

속B2

조원소개

조장 강승우자료조사 강성태 김남희 고충욱

프로그래밍 김도형 과제수행기간

3주 6 시간

주 제연구제목

말의 이동

참 고 자 료

참고

URL

※ 출처 : 네이버 지식인

http://kin.naver.com/qna/detail.nhn?

d1id=1&dirId=1040101&docId=64601805&qb=aW5maXggcG9zdGZpeCDrsJTqvrjri

pQg67Cp67KV&enc=utf8&section=kin&rank=4&search_sort=0&spq=0

※ 출처 : 네이버 블로그

(http://cafe.naver.com/clickhdwork.cafe?iframe_url=/ArticleRead.nhn

%3Farticleid=709&)

과제의 수행

첫째

날2012년 3월 27일 화요일

회의

주제조원 자기소개 및 역할분담, 과제 파악

회의

내용

※말의 여행에 대한 문제 파악

이번과제는 말이 장기판위를 이동하는 좌표를 출력하는 과제이다.

과제에 필요한 개념들은 스택, 큐, 백트래킹, infix expression, postfix expression 이

있고 파스칼 삼각형과제에 있었던 시간복잡도와 공간복잡도의 계산도 있기에

공부를 하였지만 부족했던 시간복잡도와 공간복잡도에 대한 개념조사와 이해를

세밀하게 해보기로 하였습니다. 그리고 말의 여행에 대한 프로그램을 설계를

하기위해 알고리즘 조사를 하기로 하여 역할분담을 하였습니다.

 보고서 작성 : 강승우

프로그래밍 : 김도형

자료조사 : 고충욱, 강성태, 김남희

문제 - 과제에 대한 사전조사 부족

Page 2: 자료구조 Project2

반성과제에 대한 사전조사가 없었기 때문에 토의 범위를 넓게 하지못하여

많은 내용을 토의하지 못하였습니다.둘째

날2012년 3월 29일 목요일

회의

주제조사해온 자료들의 개념이해, 프로그램 소스의 설계 방법

회의

내용

스택

∎기억 장치에 데이터를 일시적으로 겹쳐 쌓아 두었다가 필요할 때에 꺼내서 사용할 수 있게

주기억장치(main memory)나 레지스터(register)의 일부를 할당하여 사용하는

임시 기억장치를 말한다.

∎스택의 최상단 데이터 위치를 가리켜주는 변수를 탑(top)이라고 한다.

∎탑 한쪽끝에서만 삽입과 삭제의 연산(operation)이 일어나는 순서 리스트를 말한다.

※ 출처 : 네이버 지식사전

∎리스트의 한쪽 끝에서만 삽입과 삭제가 일어나는 스택과는 달리 리스트의 한쪽

끝에서 는 원소들이 삭제되고 반대쪽 끝에서는 원소들의 삽입만 가능하게 만든

순서화된 리스트.

※ 출처 : 네이버 지식사전

백트래킹(퇴각검색)

∎문제의 해를 탐색하는 체계적인 방법

∎주어진 조건을 만족하는 최적해 또는 해들의 집합들을 찾는 문제를 대상으로 하며,

효율적인 알고리즘이 존재하지 않을 때 사용한다.

∎백트래킹을 사용하기 위해 재귀에 대하여 알아야 한다.

⋅재귀

- 함수내에서 직접적 혹은 간접적으로 자기 자신을 호출하는 것

- 주의 할 점

① 반드시 종료조건이 있어야 한다.

② 단순하게 코딩 할 수 있다.

③ 내부적으로 스택 메모리(정적영역)를 사용한다.

④ 과다 호출시 스택 오버플러가 발생 할 수 있다.

Page 3: 자료구조 Project2

infix expression(중위 연산자) => postfix expression(후위 연산자)

∎ 연산자의 infix 표기를 postfix 로 바꿀 때에는 대개 스틱을 이용합니다

∎ 모든 수식을 연산자, 피연산자로 구분합니다. 이때, 연산자, 피연산자 각각이 하나의

단위로 동작하게 된다.

① 수식에서 첫번째 항목을 빼냅니다.

② 수식의 빼낸 항목이 피연산자라면 그대로 출력측으로 빼냅니다

③ 수식의 빼낸 항목이 연산자라면 스택의 최상위 원소와 비교합니다.

④ 빼낸 연산자의 우선순위가 스택의 최상위에 있는 원소보다 높으면 그대로

스택에 넣습니다.

⑤ 그렇지 않다면 스택의 최상위 원소를 출력측으로 뺴내고 빼낸 연산자를

스택에 넣습니다.

⑥ 단, 여는 괄호'('가 나오면 닫는괄호')'가 나올 때까지 스택에 남아있게 되며,

닫는괄호')'가 나타나면 그때까지 여는괄호'('보다 상위에 있는 모든 연산자를

출력측으로 빼냅니다.

위의 자료조사를 통해서 백트래킹은 말의 이동경로가 막혔을때 왔던 좌표를 하나씩

뒤로 돌아가면서 이동경로가 있는지 확인해 주는 역할을 하고 그것을 저장 해두는게

스택이고 화면에 출력을 할때 차례대로 하기위해 큐를 사용하는 것 같다는 토의내용이

나왔고 이를 통해 스택, 큐, 백트래킹은 함수가 아닌 그냥 용어 라는것을 알아냈습니다.

문제

- 개념들의 이해부족

- 프로그램과 조사한 자료들의 연관성

반성

자료조사해온 개념들에 대한 토의를 하였는데 프로그램을 설계하면서 개념들이

프로그램에 어떻게 쓰이는지 그 연관성의 대한 이해가 부족하여 더 세밀한 자료조사를 통해 각자의 생각을 토의하도록 해야겠습니다.

셋째

날2012년 4월 03일 화요일

회의

주제시간복잡도와 공간복잡도 이해

회의

내용공간복잡도

주어진 알고리즘을 실행시키기 위해 필요한 기억장치(space)는 다음과 같이 두 가지로 분류해

볼 수 있다.

1.알고리즘과 무관한 부분: 알고리즘의 특성과는 무관한 부분으로 프로그램 코드를 저장하기

Page 4: 자료구조 Project2

위한 공간, 프로그램을 수행하기 위해 시스템이 필요로 하는 공간 등이 이에 포함된다.

2.알고리즘과 밀접한 부분: 알고리즘의 특성과 밀접한 관계가 있는 부분으로서 문제를 해결하기

위해 필요로 하는 공간을 의미한다. 즉, 변수를 저장하기 위한 공간이나 순환 프로그램일 경우

순환 스택(recursion stack) 등이 이에 포함된다.

일반적으로 알고리즘의 공간 복잡도를 분석할때는 위의 두가지중 두 번째의 것을 계산하게

된다. 즉, 알고리즘이 문제를 해결하기 위해서 반드시 필요한 부분만을 계산함으로써 주어진

알고리즘의 공간 복잡도를 계산한다.

다음은 공간 복잡도를 구하는 예이다.

[예제 4.1] 공간 복잡도의 계산 1

float abc(float a, float b, float c)

{

return(a + b + b*c + (a + b - c)/(a + b) + 4.0);

}

공간 복잡도 = 0

위의 프로그램에서 공간복잡도를 구하기 위해서 살펴볼 것은 변수 a, b, c 이다. 따라서, float

형의 변수가 한 워드(word)를 차지한다고 가정하면, 공간복잡도는 '3워드'라고 생각할 수 있다.

그러나 변수 a, b, c 는 전달되는 인자(parameter)로서 함수 abc 내에서 해결하고자 하는

문제와는 무관하다고 볼 수 있으므로 공간 복잡도는 0 이다.

[예제 4.2] 공간 복잡도 계산 2

float Sum(float a[], int n)

{

float s = 0.0;

for(int i = 1; i < = n; i++)

s += a[i];

return s;

}

공간 복잡도 = n + 3

위의 프로그램에서 사용되는 변수는 a[], n, s, i 이다. 이번 예에서도 a[]와 n 은 인자로 전달

됨을 볼 수 있다. 그러나 [예제 4.1]과는 다르게 변수 a[]는 합을 구하기 위하여 반복문 내에서 n

개의 원소가 모두 참조되고 있음을 볼 수 있다. 또한, n 은 for-문을 벗어나기 위한 한계값으로

사용된다. 따라서 a[]와 n 은 알고리즘이 해결하고자 하는 문제와 밀접한 관련이 있다고 볼 수

있다. 그러므로 프로그램의 복잡도는 (a[]를 저장하기 위한 공간) + (변수 n, s, I 를 위한 공간)

= n + 3 이 된다.

Page 5: 자료구조 Project2

[예제 4.3] 공간 복잡도 계산 3

float RSum(float a[], int n)

{

if(n <= 0)

return (0.0);

else

return (RSum(a, n-1) + a[n]);

}

공간 복잡도 = 3(n + 1)

위의 프로그램은 순환기법(resursion)으로 작성된 것이다. 위의 경우 살펴볼 변수는 a[], n

이다. 우선 변수 n 은 if-문 내에서 순환의 한계값으로 사용되고 있음을 볼 수 있다. 또한, 변수

a[]는 합을 구하기 위하여 사용되고 있으며 a[]의 원소 중에서 n 번째의 원소만 필요로 한다.

따라서 변수 a[]와 n 이 모두 알고리즘과 밀접한 관계가 있으므로, 프로그램이 필요로 하는

공간은 (a[]의 n 번째 원소를 의한 공간) + (n 을 위한 공간) = 1 + 1 으로 볼 수 있다. 그러나

위의 프로그램은 순환기법에 의해 작성되었음을 고려해야 한다. 즉, 프로그램이 순환적으로

실행될 것을 고려해서 몇번의 순환후에 실행이 종료되는지(the depth of recursion)를

계산해야 하며, 또한 순환을 위해서 필요한 복귀 주소(return address)를 저장할 공간도

계산해야 한다. 그러므로 프로그램의 공간 복잡도는 (depth of recursion)×(a[n], n, 복귀

주소를 위한 공간) = (n+1)×3 이 된다.

문제

점-정확한 시간 공간복잡도 이해 부족

반성토의를 했음에도 불구하고 복잡도의 이해가 부족하였습니다. 개인적으로 보충을하여

다시 토의를 해야겠습니다.넷째

날2012년 4월 5일 목요일

회의

주제프로그램 초안 토의

회의

내용

#include <stdio.h>#define X_SIZE 9

#define Y_SIZE 10

#define NUM_WAYS 8

#define LONG 90

typedef int board_t[X_SIZE][Y_SIZE];

int dx[NUM_WAYS] = {-2, -1, 1, 2, 2, 1, -1, -2};

int dy[NUM_WAYS] = {1, 2, 2, 1, -1, -2, -2, -1};

Page 6: 자료구조 Project2

int ax[LONG];

int ay[LONG];

void print_board(board_t board)

{

int i, j;

for (i=0; i<X_SIZE; i++)

{

for (j=0; j<Y_SIZE; j++)

printf("%d\t", board[i][j]);

printf("\n");

}

}

void Start(board_t board)

{

int i, j;

for (i=0; i<X_SIZE; i++)

for (j=0; j<Y_SIZE; j++)

board[i][j] = -1;

}

int InBoard(int x, int y)

{

return x >= 0 && x < X_SIZE && y >= 0 && y < Y_SIZE;

}

int Access(board_t board, int x, int y)

{

return InBoard(x, y) && board[x][y] == -1;

}

int num_next_moves(board_t board, int x, int y)

{

int i, result=0;

for (i=0; i<NUM_WAYS; i++)

if (Access(board, x+dx[i], y+dy[i]))

result++;

return result;

}

int main()

{

int x, y, move=1, next,test;

board_t board;

Start(board);

Page 7: 자료구조 Project2

while (1)

{

printf("시작좌표를 입력하세요 ");

scanf("%d %d", &x, &y);

if (InBoard(x, y)) break

printf("장기판을 벗어난 좌표입니다\n");

}

board[x][y] = 0;

ax[0]=x;

ay[0]=y;

for(move=1; move < X_SIZE*Y_SIZE; move++)

for(next=0;next<8;next++)

{

x = x + dx[next];

y = y + dy[next];

test=Access(board,x,y);

if(test!=1)

{

x = x - dx[next];

y = y - dy[next];

}

else

{

if(num_next_moves(board, x, y)==0)

{

x = x - dx[next];

y = y - dy[next];

}

else

{

if(x==ax[move]&&y==ay[move])

{

board[x][y] = -1;

x = x - dx[next];

y = y - dy[next];

continue

}

board[x][y] = move;

ax[move]=x;

ay[move]=y;

Page 8: 자료구조 Project2

break

}

}

}a

for(move=0;move<90;move++)

printf("%d,%d ",ax[move],ay[move]);

printf("\n");

print_board(board);

}

문제

점스택 사용이 안되었고 장기판을 모두 채우지 못하고 프로그램이 종료된다.

반성아직 스택 구현을 제대로 하지못하고 있습니다. 더욱더 노력하여 스택 구현에 힘을 써야 겠습니다.

결과 발표프로

그램

소스

#include <stdio.h>

/* definitions */

#define X_SIZE 10

#define Y_SIZE 9

#define ways 8

#define LONG 90

typedef int board_t[X_SIZE][Y_SIZE];

int dx[ways] = {-2, -1, 1, 2, 2, 1, -1, -2};

int dy[ways] = {1, 2, 2, 1, -1, -2, -2, -1};

// Stack 선언부

int STX[LONG] = {0};

int STY[LONG] = {0};

int s_t=-1;//stack_top

int s_way=0;

void add_s(int x,int y)

{

STX[++s_t]=x;

STY[s_t]=y;

}

int pop_x()

{

return STX[s_t];

}

Page 9: 자료구조 Project2

int pop_y()

{

return STY[s_t--];

}

//출력 함수 선언부

void print_point(board_t board)

{

int u;

for(u=0; u<90; u++)

printf("(%d,%d) ",STX[u],STY[u]);

}

void print_board(board_t board)

{

int i, j;

for (i=0; i<X_SIZE; i++)

{

for (j=0; j<Y_SIZE; j++)

printf("%d\t", board[i][j]);

printf("\n");

}

}

//조건 함수 선언부

void Start(board_t board)//배열 -1 로 초기화

{

int i, j;

for (i=0; i<X_SIZE; i++)

for (j=0; j<Y_SIZE; j++)

board[i][j] = -1;

}

int InBoard(int x, int y)//장기판 안에 있는지 판별

{

return x >= 0 && x < X_SIZE && y >= 0 && y < Y_SIZE;

}

int Access(board_t board, int x, int y)//장기판 안에 있고 중복이동이 아닌지 판별

{

Page 10: 자료구조 Project2

return InBoard(x, y) && board[x][y] == -1;

}

int NextMoves(board_t board, int x, int y)//움직일수 있는 경로가 몇군대인지 result 값을

카운트 한다

{

int i, result=0;

for (i=0; i<ways; i++)

if (Access(board, x+dx[i], y+dy[i]))

result++;

return result;

}

int new_move(board_t board, int x, int y);

int MinNextWay(board_t board, int x, int y)//다음 움직일수있는 경우가 가장 작은곳으로

이동한다(단 이동경로가 0 이 아닌 경우)

{

int i, min = ways, result=0;

for (i=0; i<ways; i++)

if (Access(board, x+dx[i], y+dy[i]) && NextMoves(board, x+dx[i], y+dy[i]) < min)

{

min = NextMoves(board, x+dx[i], y+dy[i]);

result = i;

}

return result;

}

void InPoint(board_t board, int x, int y)

{

int way;

for (;s_t+1<X_SIZE*Y_SIZE;)

{

if (NextMoves(board, STX[s_t], STY[s_t]) == 0)

{

board[x][y] = -1;

pop_x();

pop_y();

}

way = MinNextWay(board, x, y);

Page 11: 자료구조 Project2

x = x + dx[way];

y = y + dy[way];

add_s(x,y);

board[x][y] = s_t;

}

}

int ssway[90]={0};

void Rway(board_t board, int x,int y)//x=stx, y=sty

{

printf("s_t?%d\n",s_t);

printf("ssway[s_t]?%d\n",ssway[s_t+1]);

if(s_t>=87)//스텍이 90 개 쌓이면 끝내기

{

printf("쫑");

return;

}

else if(InBoard(x, y)&&NextMoves(board, x, y)>0)

{

printf("들왔? %d\n",ssway[s_t+1]);

x = STX[s_t] + dx[ssway[s_t+1]];

y = STY[s_t] + dy[ssway[s_t+1]];

if(Access(board, x, y))//이동한곳이 되는 자리면 ?

{

printf("들왔 A %d\n",ssway[s_t+1]);

add_s(x,y);

board[STX[s_t]][STY[s_t]] = s_t;

Rway(board,STX[s_t],STY[s_t]);//제귀 실행

}

else if(ssway[s_t+1]>=7)//8 번째 경우까지 이동할곳이 없으면 팝

{

printf("빠꾸 2\n");

board[STX[s_t]][STY[s_t]] = -1;

ssway[s_t+1]=0;

pop_x();

pop_y();

Page 12: 자료구조 Project2

ssway[s_t+1]++;//팝한곳 다른길로

Rway(board,STX[s_t],STY[s_t]);

}

else

{

printf("빠꾸 1\n");

ssway[s_t+1]++;

printf("%d\n",ssway[s_t+1]);

Rway(board,STX[s_t],STY[s_t]);

}

}

else

{

printf("빠꾸 3\n");

board[STX[s_t]][STY[s_t]] = -1;

ssway[s_t+1]=0;

pop_x();

pop_y();

ssway[s_t+1]++;//팝한곳 다른길로

Rway(board,STX[s_t],STY[s_t]);

}

}

int main()

{

int x,y, way=0;

board_t board;

Start(board);

while (1)

{

printf("시작좌표를 입력하시오 ");

scanf("%d %d", &x, &y);

fflush(stdin);

if (InBoard(x, y)) break;

printf("장기판 벗어난 좌표입니다\n");

}

Page 13: 자료구조 Project2

add_s(x,y);

board[STX[s_t]][STY[s_t]] = s_t;

printf("%d,%d",STX[s_t],STY[s_t]);

printf("%d\n",board[STX[s_t]][STY[s_t]]);

Rway(board, STX[s_t], STY[s_t]);

//InPoint(board,STX[s_t],STY[s_t]);

print_board(board);

print_point(board);

}

Page 14: 자료구조 Project2

최종 반성

되돌아오는 퇴각 검색을 계속할 경우 프로그램 오버플로어 오류가 나므로 휴리스틱의 법칙을 이용하여 문제를 해결하였 습니다.