프로그래머스 입문 120844 배열 회전시키기
문제
배열의 원소를 direction 방향으로 한 칸씩 회전시키시오.
| numbers | direction | result |
|---|---|---|
| [1, 2, 3] | “right” | [3, 1, 2] |
| [4, 455, 6, 4, -1, 45, 6] | “left” | [455, 6, 4, -1, 45, 6, 4] |
풀이
[1, 2, 3]을 오른쪽으로 회전시키면 각 원소의 인덱스는 다음처럼 바뀐다.
0 -> 1
1 -> 2
2 -> 0
2 -> 0처럼 마지막 원소가 처음으로 돌아가는 경우를 제외하면, 원본 배열의 n번 인덱스 값은 결과 배열의 n + 1번 인덱스로 이동한다.
[4, 455, 6, 4, -1, 45, 6]을 왼쪽으로 회전시키면 각 원소의 인덱스는 다음처럼 바뀐다.
0 -> 6
1 -> 0
2 -> 1
3 -> 2
4 -> 3
5 -> 4
6 -> 5
0 -> 6처럼 첫 원소가 마지막으로 돌아가는 경우를 제외하면, 원본 배열의 n번 인덱스 값은 결과 배열의 n - 1번 인덱스로 이동한다.
방향별로 한 칸씩 옮기기
#include <stdlib.h>
#include <string.h>
int* solution(int numbers[], size_t numbers_len, const char* direction)
{
int* result = (int*)malloc(sizeof(int) * numbers_len);
if (strcmp(direction, "right") == 0)
{
for (int i = 0; i < numbers_len - 1; i++)
{
result[i + 1] = numbers[i];
}
result[0] = numbers[numbers_len - 1];
}
else
{
for (int i = 1; i < numbers_len; i++)
{
result[i - 1] = numbers[i];
}
result[numbers_len - 1] = numbers[0];
}
return result;
}
위에서 설명한 인덱스 이동 규칙을 그대로 코드로 옮긴 것이다.
오른쪽으로 회전할 때는 원본 배열의 i번 인덱스 값을 결과 배열의 i + 1번 인덱스에 대입한다.
원본 배열의 마지막 값은 결과 배열의 첫 번째 칸으로 돌아가야 하므로 따로 처리한다.
왼쪽으로 회전할 때는 원본 배열의 i번 인덱스 값을 결과 배열의 i - 1번 인덱스에 대입한다.
원본 배열의 첫 번째 값은 결과 배열의 마지막 칸으로 돌아가야 하므로 따로 처리한다.
나머지 연산으로 순환 위치 구하기
#include <stdlib.h>
#include <string.h>
int* solution(int numbers[], size_t numbers_len, const char* direction)
{
int* result = (int*)malloc(sizeof(int) * numbers_len);
if (strcmp(direction, "right") == 0)
{
for (int i = 0; i < numbers_len; i++)
{
result[(i + 1) % numbers_len] = numbers[i];
}
}
else
{
for (int i = 0; i < numbers_len; i++)
{
result[i] = numbers[(i + 1) % numbers_len];
}
}
return result;
}
이전 방법은 대부분의 원소를 한 칸씩 옮긴 뒤, 범위를 벗어나는 값만 따로 처리했다.
그래서 오른쪽 회전에서는 마지막 원소를, 왼쪽 회전에서는 첫 번째 원소를 따로 다루는 코드가 필요했다.
나머지 연산자를 사용하면 범위를 벗어나는 인덱스도 다시 유효한 인덱스로 바꿀 수 있다.
오른쪽으로 회전할 때는 결과 배열의 인덱스를 (i + 1) % numbers_len으로 계산한다.
그러면 i + 1이 배열의 길이와 같아지는 순간 나머지가 0이 되어 마지막 값이 첫 번째 칸으로 들어간다.
왼쪽으로 회전할 때는 결과 배열의 i번 인덱스에 원본 배열의 (i + 1) % numbers_len번 인덱스 값을 넣는다.
그러면 마지막 인덱스에서 다음 값을 가져오려고 할 때 나머지가 0이 되어 원본 배열의 첫 번째 값을 가져올 수 있다.