프로젝트로 만든 2차원 배열을 이용한 마방진을 만들었다.
사용자로부터 홀수 n을 입력 받아 n * n 의 마방진 만들기
마방진이란?
1에서 n제곱까지의 수를 정사각형으로 배열해 가로, 세로, 대각의 합계도 모두 같도록 만드는 것이다.
처음에 봤을 때는 막막해서 마방진에 대해 자세히 고민해봤다.
처음 나왔던 구상은 2차원 배열을 모두 0으로 채우고 각 규칙대로 if문을 통해 숫자를 입력하는 것이었다. 각 규칙마다 조건문을 다는 것은 너무 복잡했고 번거로웠다.
그래서 규칙에 대해 더 고민해봤다.
1의 대각선 아래에는 무조건 입력받은 홀수가 오게되었고 입력 받은 홀수의 배수들은 모두 하나 아래의 열로 이동한다.
그 규칙을 토대로 코드를 작성해보니 더욱더 간결하게 코딩이 가능하게 되었다.
마방진에 사용한 2차원 배열은 delete를 통해 할당을 해제해주어야 하는데
할당 해제하는 것이 익숙치 않아서 해제하지 않았는데 해제를 해줘야 메모리 누수를 방지할 수 있기 때문에 꼭 해줘야한다고 피드백을 들었다.
1행의 중앙에서 1로 시작하는 코딩을 하기위해 시작지점은 '열 / 2'에서 시작하도록 한다.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int num_in = 0;
cout << " 마방진의 행 혹은 열의 수를 자연수(홀수)로 입력해주세요. : ";
while (1)
{
cin >> num_in;
if (num_in % 2 == 1) { break; }
else cout << "홀수를 입력해주세요." << endl;
}
int start = num_in / 2; //1행의 중앙 설정
int row = 0; // 행
int col = start; //열 , 숫자는 1행의 중앙에서 1부터 시작
int total_number = num_in * num_in; //마방진에 들어갈 총 숫자
//2차원 배열 선언하기
{
int** num_arr = new int* [num_in];
for (int i = 0; i < num_in; i++)
{
num_arr[i] = new int[num_in]; // 각각의 행에 크기가 num인 배열을 할당
}
//입력값 x 입력값 원소 생성 후 조건에 맞게 집어넣기
for (int k = 1; k <= total_number; k++)
{
num_arr[row][col] = k; //1행의 중앙에서 1부터 숫자 시작하기.
if (k % num_in == 0) { row++; } //입력한 숫자와 같으면 열을 아래로
else // 아니라면 열은 한 칸 위로(--), 행은 옆으로(++)
{
row--;
col++;
}
if (row < 0) //행이 맨위(row < 0)를 넘었을경우 맨 밑(num_in - 1)으로 이동
{
row = num_in - 1;
}
if (col >= num_in) //열이 맨 마지막 (col >= num_in)을 넘었다면 맨 앞으로(col = 0) 이동
{
col = 0;
}
}
//배열 출력하기
for (int i = 0; i < num_in; i++)
{
for (int j = 0; j < num_in; j++)
{
cout << num_arr[i][j] << " ";
}
cout << endl;
}
//배열 해제하기
for (int k = 0; k < num_in; k++)
{
delete[] num_arr[k];// 안쪽 배열 해제
}
delete[] num_arr;// 바깥 배열 해제
}
return 0;
}