거북이처럼 천천히

C - [혼공c] 14장 도전 실전 예제 (가로 세로의 합 구하기) 본문

Algorithm/알고리즘 문제 풀이

C - [혼공c] 14장 도전 실전 예제 (가로 세로의 합 구하기)

유로 청년 2024. 6. 19. 12:39

1. 문제

문제 제목 : 가로 세로의 합 구하기

 

2. 생각

목표) 문제의 범용성을 높이기 위해 5행 6열 뿐만 아니라 행과 열 값을 받아서 2차원 배열을 생성한 뒤, 그에 대한 각 열과 행의 합을 구하여 2차원 배열의 끝에 저장하자.

 

  1. 가변 길이를 갖는 2차원 배열을 생성하기 위해 malloc 함수 사용
  2. 중요) 각 열에 대한 1차원 가변 길이를 갖는 배열을 생성하기 위해 추가적으로 malloc 함수 사용
  3. (0, 0) 부터 시작해서 값을 대입하는 과정인 초기화 작업 수행
  4. 각 행과 열의 합을 구해 대입

 

3. 풀이 및 코드 분석

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

// Function prototype.
void get_size_of_board(unsigned short* max_row, unsigned short* max_col);
void init_board(unsigned short** board, unsigned short max_row, unsigned short max_col);
void get_sum_of_row_and_col(unsigned short** board, unsigned short max_row, unsigned short max_col);
void print_the_board(unsigned short** board, unsigned short max_row, unsigned short max_col);

// Main method.
int main(void) {
	unsigned short max_row = 0, max_col = 0;

	// Get size of board.
	get_size_of_board(&max_row, &max_col);

	// 포인트 배열 선언.
	unsigned short** board = (unsigned short**)malloc((max_row+1) * (unsigned int)sizeof(unsigned short*));

	// 각 행에서 포인트 배열 선언
	for (unsigned short row = 0; row <= max_row; row++)
		board[row] = (unsigned short*)malloc((max_col+1) * (unsigned int)sizeof(unsigned short));

	// Initialization.
	init_board(board, max_row, max_col);

	// Get sum of row, col.
	get_sum_of_row_and_col(board, max_row, max_col);

	// Print the board.
	print_the_board(board, max_row, max_col);

	// free
	for (unsigned short row = 0; row <= max_row; row++)
		free(board[row]);
	free(board);

	return 0;
}

// Get size of board.
void get_size_of_board(unsigned short* max_row, unsigned short* max_col) {
	while (1) {
		printf("행과 열을 입력 : ");
		scanf_s("%hu %hu", max_row, max_col);

		if (max_row <= 0 || max_col <= 0) puts("잘못된 행과 열을 입력하셨습니다.");
		else return;
	}
}

// Initialization.
void init_board(unsigned short** board, unsigned short max_row, unsigned short max_col) {
	for (unsigned short row = 0; row < max_row; row++)
		for (unsigned short col = 0; col < max_col; col++)
			board[row][col] = row * max_col + col + 1;
}

// Get sum of row & col.
void get_sum_of_row_and_col(unsigned short** board, unsigned short max_row, unsigned short max_col) {
	unsigned short* list_of_sum = (unsigned short*)calloc(max_col, sizeof(unsigned short));

	for (unsigned short row = 0; row < max_row; row++) {
		unsigned short sum = 0;

		for (unsigned short col = 0; col < max_col; col++) {
			list_of_sum[col] += board[row][col];
			sum += board[row][col];
		}

		board[row][max_col] = sum;
	}

	for (unsigned short col = 0; col < max_col; col++)
		board[max_row][col] = list_of_sum[col];

	free(list_of_sum);
}

// Print the board.
void print_the_board(unsigned short** board, unsigned short max_row, unsigned short max_col) {
	printf("Board = \n");

	for (unsigned short row = 0; row <= max_row; row++) {
		for (unsigned short col = 0; col <= max_col; col++)
			printf("%5hhu", board[row][col]);
		printf("\n");
	}
}

 

 

출력 콘솔 창

 

 

  • 2차원 포인트 배열을 선언할 때에는 아래와 같이 두 번의 과정을 거치게 된다.
    1단계) 2차원 포인트 배열을 동적 메모리 할당을 받는다.
               (아직 각 원소들은 포인트 배열을 할당 받지 못한 상태)
    2단계) 반복문을 이용하여 각 원소들에 대해서 동작 메모리 할당을 받는다.
  • 동적 메모리 할당 받은 것을 다시 운영체제로 반환할 때에도 각각에 대해서 반환해야 할 것이며, 각각의 포인트 배열을 원소로 갖는 포인트 배열에 대해서도 free함수를 통해 반환해햐 할 것이다.
// 포인트 배열 선언.
unsigned short** board = (unsigned short**)malloc((max_row+1) * (unsigned int)sizeof(unsigned short*));

// 각 행에서 포인트 배열 선언
for (unsigned short row = 0; row <= max_row; row++)
	board[row] = (unsigned short*)malloc((max_col+1) * (unsigned int)sizeof(unsigned short));
// free
for (unsigned short row = 0; row <= max_row; row++)
	free(board[row]);
free(board);

 

 

4. 메모

  • 2차원 배열 (포인트 배열)을 어떻게 동적할당 받을 수 있는지에 대해서 생각할 수 있었던 기회였다.

 

5. 문제 출처

- 한빛미디어, 혼자 공부하는 C언어, 저자 서현우