2015. 5. 9. 19:29

"AlgoSpot DRAWRECT 문제 풀이"에 대한 2가지 코드를 준비해 봤습니다. 그중에서 첫번째로 절차지향적으로 문제를 풀어보는 코드입니다. 알고리즘 자체를 코드로 변환하는 방법에 대해서 익숙하지 않거나, 사람이 인식할 수 있는 코드를 작성하는 방법을 잘 모르시는 분들을 위해 준비한 것입니다.


컴퓨터가 이해하는 코드는 어느 바보나 다 짤 수 있다. 훌륭한 프로그래머는 사람이 이해할 수 있는 코드를 짠다.

- 마틴 파울러 : Martin Fowler (리팩토링 저자).


▶ 주 플로우 챠트 작성 (Draw main flow chart)


앞서 알고리즘 문제 풀이에서 기술한 흐름을 순서도(flow chart)로 작성해 봅니다. 논리 전개에 익숙하지 않은 분들은 가급적 바로 코딩에 뛰어들지 마시고, 귀찮더라고 문제를 풀 때마다 플로우 차트를 그리는 연습을 해야 합니다. 그리고 가급적이면, 파워포인트 혹은 플로우 챠트 그리는 도구를 사용하지 말고, 직접 종이에 그려 보는 것을 권장합니다. 그래야 좀 더 논리적인 전개에 집중할 수 있습니다. 플로우 차트를 도구 없이도 머리 속에서 그릴 수 있게 되면, 그 다음에는 종이나 파워포인트 없이 바로 코딩을 시작해도 됩니다.




▶ 서브루틴 플로우 챠트 작성 (Draw subroutine flow chart)


주된 흐름을 플로우 차트로 작성한 후에는 서브루틴(subroutine)에 대한 플로우 차트를 작성합니다. 플로우 차트 하나에 모든 논리(logic0을 담을 수 없습니다. 달리 말해서, 하나의 플로우 차트에 단계가 10~20개 정도가 좋은 것이고 그 보다 많은 단계를 하나의 플로우 차트에 그려 넣는다는 것은 플로우 차트를 쪼갤 필요가 있다는 얘기가 됩니다. 문제를 한 눈에 알아보고, 전체 흐름을 파악할 수 있을 정도가 되어야 버그(bug)를 최대한 방지할 수 있습니다. 또한 플로우 차트를 쪼개는 과정에서 부수적으로 서브루틴(subroutine) 혹은 함수(function)를 도출해낼 수 있다는 점도 플로우 차트를 권장하는 이유입니다.




▶ 절차적 코드 작성


절차적 프로그래밍 패러다임을 적용하기 위해 C 언어로 작성하였습니다. 아래 코드를 보시면, 여러 개의 좌표를 저장하기 위해 구조체(struct)를 사용하신 것을 확인할 수 있습니다. 논리(logic)도 중요하지만, 프로그래밍 언어들에서 제공하는 구조체 등을 활용하면 보다 사람이 이해하기 좋은 코드 (직관적이고, 가독성 높은)를 작성하실 수 있습니다.


#include <stdio.h>
#include <stdlib.h>

/* x,y 좌표를 표현하는 점(point) 구조체를 정의한다. */ 
typedef struct {
   int x;
   int y;
} point;

int main(int argc, char *argv[]) {
	
	// 테스트 케이스 반복 횟수 및 좌표 변수 생성 및 초기화 
	int cnt = 0;
	point p1 = {0, 0};
	point p2 = {0, 0};
	point p3 = {0, 0};
	point p4 = {0, 0};
	
	// 테스트 케이스 반복 횟수 입력. 
	int testCaseCount;
	printf("Input test case number : ");
	scanf("%d", &testCaseCount); 
	
	// 입력 받은 테스트 케이스 수만큼 반복 처리... 
	for(cnt=0; cnt<testCaseCount; cnt++) {
		
		// pt, p3, p3 등 3개의 좌표 값 입력 
		printf("Input p1 (x, y) : ");
		scanf("%d %d", &p1.x, &p1.y);
		printf("p1.x = %d, p1.y = %d\n", p1.x, p1.y);
		
		printf("Input p2 (x, y) : ");
		scanf("%d %d", &p2.x, &p2.y);
		printf("p2.x = %d, p2.y = %d\n", p2.x, p2.y);
		
		printf("Input p3 (x, y) : ");
		scanf("%d %d", &p3.x, &p3.y);
		printf("p3.x = %d, p3.y = %d\n", p3.x, p3.y);
		
		// 4번째 좌표 계산  (p1 ~ p3는 입력, p4 는 출력 용도의 인자[argument]) 
		int returnCode = calculateP4(&p1, &p2, &p3, &p4);
		
		// 정상적으로 계산된 경우, 네번째 좌표 출력 
		if(returnCode == 0) {
			printf("Result p4.x = %d, p4.y = %d", p4.x, p4.y );
		} 
		// 잘못된 입력 좌표가 존재할 경우, 에러 메시지 출력 및 프로그램 종료. 
		else {
			printf("Error : Invalid coordinate");
			return 1;
		}
		
	}

	return 0;
}

/*
 * p1, p2, p3 등 3개의 좌표 값을 입력받아, p4 좌표 계산.
 *
 * 만일, 잘못된 자표가 입력된 경우 -1 반환, 정상적으로 좌표를 계산한 경우 0 반환. 
 */
int calculateP4(point *p1, point *p2, point *p3, point *p4) {

	// p4.x 좌표 계산 
	if(p1->x == p2->x) {
		p4->x = p3->x;
	} else if(p1->x == p3->x) {
		p4->x = p2->x;
	} else if(p2->x == p3->x) {
		p4->x = p1->x;
	} else {
		return -1;
	}
	
	// p4.y 좌표 계산 
	if(p1->y == p2->y) {
		p4->y = p3->y;
	} else if(p1->y == p3->y) {
		p4->y = p2->y;
	} else if(p2->y == p3->y) {
		p4->y = p1->y;
	} else {
		return -1;
	}
	
	return 0;
}


▶ 실행 결과


위와 같은 코드의 실행 결과(예시)는 아래와 같습니다.


Input test case number : 1

Input p1 (x, y) : 10 30

p1.x = 10, p1.y = 30

Input p2 (x, y) : 45 30

p2.x = 45, p2.y = 30

Input p3 (x, y) : 10 65

p3.x = 10, p3.y = 65


Result p4.x = 45, p4.y = 65


Posted by 곽중선