2차원 배열 지그재그로 채우기
문제
1 2 3 4 5
10 9 8 7 6
11 12 13 14 15
20 19 18 17 16
21 22 23 24 25
풀이
행 방향에 따라 반복문을 나누는 방법
#include <stdio.h>
int main(void)
{
int arr[5][5];
int count = 1;
for (int i = 0; i < 5; i++)
{
if (i % 2 == 0)
{
for (int j = 0; j < 5; j++)
{
arr[i][j] = count++;
}
}
else
{
for (int j = 4; j >= 0; j--)
{
arr[i][j] = count++;
}
}
}
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%2d ", arr[i][j]);
}
printf("\n");
}
return 0;
}
문제를 보면 0, 2, 4번 행은 순방향으로 숫자가 채워지고, 1, 3번 행은 역방향으로 숫자가 채워진다.
나머지 연산자 %를 이용해 짝수 행인지 판별한 뒤, 행의 방향에 맞게 숫자를 넣는다.
역방향으로 채울 때 j를 4부터 감소시키는 대신 0부터 증가시키면서 arr[i][4 - j]에 값을 넣을 수도 있다.
열 인덱스를 계산하는 방법
#include <stdio.h>
int main(void)
{
int arr[5][5];
int count = 1;
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
int col = i % 2 == 0 ? j : 4 - j;
arr[i][col] = count++;
}
}
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%2d ", arr[i][j]);
}
printf("\n");
}
return 0;
}
바깥 반복문과 안쪽 반복문 사이에 있던 if, else를 삼항 연산자로 바꾸면 for 문 두 개가 연속해서 보여 전체 흐름이 더 잘 보인다.
행마다 시작값과 증감값을 바꾸는 방법
#include <stdio.h>
int main(void)
{
int arr[5][5] = { 0 };
int count = 0;
int sign = 1;
for (int i = 0; i < 5; i++)
{
if (i % 2 == 0) count = i * 5;
else count = (i + 1) * 5 + 1;
for (int j = 0; j < 5; j++)
{
count += sign;
arr[i][j] = count;
}
sign = -sign;
}
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%2d ", arr[i][j]);
}
printf("\n");
}
return 0;
}
주어진 문제를 풀기에는 과한 접근이다.
다만 배열을 채우는 방향은 순방향으로 고정하고, 행마다 시작값과 증감값을 바꿔 해결하는 흥미로운 방법이다.
순방향으로 값을 채우되, 값이 항상 증가하는 것은 아니다.
행마다 count의 시작값과 sign의 부호를 바꿔 지그재그 결과를 만든다.
짝수 행에서는 count를 i * 5로 맞춰 0, 10, 20을 기준값으로 삼는다.
이때 sign이 1이므로 안쪽 반복문에서 count가 1씩 증가한 뒤 1, 11, 21부터 값이 채워진다.
홀수 행에서는 count를 (i + 1) * 5 + 1로 맞춰 11, 21을 기준값으로 삼는다.
이때 sign이 -1이므로 안쪽 반복문에서 count가 1씩 감소한 뒤 10, 20부터 값이 채워진다.
한 행을 채운 뒤에는 sign = -sign을 실행해 다음 행에서 더할 값의 부호를 반대로 바꾼다.
sign이 1이면 -1이 되고, -1이면 다시 1이 된다.