Section 21.1: 배열의 내용을 주어진 값만큼 shift rotate 시키는 generic 메소드 예제
유의할 점 : 주어진 값이 음수일 경우에는 왼쪽으로, 양수일 경우에는 오른쪽으로 shift rotate를 수행한다.
public static void Main() {
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int shiftCount = 1;
Rotate(ref array, shiftCount);
Console.WriteLine(string.Join(", ", array));
// 출력 결과: [10, 1, 2, 3, 4, 5, 6, 7, 8, 9]
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
shiftCount = 15;
Rotate(ref array, shiftCount);
Console.WriteLine(string.Join(", ", array));
// 출력 결과: [6, 7, 8, 9, 10, 1, 2, 3, 4, 5]
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
shiftCount = -1;
Rotate(ref array, shiftCount);
Console.WriteLine(string.Join(", ", array));
// 출력 결과: [2, 3, 4, 5, 6, 7, 8, 9, 10, 1]
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
shiftCount = -35;
Rotate(ref array, shiftCount);
Console.WriteLine(string.Join(", ", array));
// 출력 결과: [6, 7, 8, 9, 10, 1, 2, 3, 4, 5]
}
private static void Rotate < T > (ref T[] array, int shiftCount) {
T[] backupArray = new T[array.Length];
for (int index = 0; index < array.Length; index++) {
backupArray[(index + array.Length + shiftCount % array.Length) % array.Length] =
array[index];
}
array = backupArray;
}
이 코드에서 중요한 부분은 shift rotate 를 시킨 이후의 인덱스를 계산해 내는 코드이다.
(index + array.Length + shiftCount % array.Length) % array.Length
아래에 조금 더 상세한 내용이 기술되어 있다:
(shiftCount % array.Length)
-> shift 를 시킬 값의 크기가 배열의 크기 한도 내에서만 존재하도록 값을 정규화 (normalize) 시킨다 (예를 들어 크기가 10 인 배열이라면, shift 연산을 1
만큼 수행하는 것과 11
만큼 수행하는 것은 동일한 결과를 나타낼 것이다. 이는 -1
과 -11
에 대해서도 동일하게 적용된다).
array.Length + (shiftCount % array.Length)
-> 이는 좌측 방향으로의 rotate 수행 시 인덱스값이 음수가 되는 것을 방지하고, 대신에 배열의 끝쪽으로 rotate 가 수행되도록 한다. 이러한 코드가 없다면 크기가 10
인 배열에 대해서 index
가 0
이고 shift 시킬 값이 -1
이라면 계산된 인덱스값은 음수 (-1
) 가 될 것이며 실제로 필요한 인덱스 값인 9
를 계산해내지 못할 것이다. (10 + (-1 % 10) = 9)
index + array.Length + (shiftCount % array.Length)
-> 위에서 설명한 방식을 이용하여 각 index
에 대해 새로이 rotate 된 인덱스 값을 계산해 낸다. (0 + 10 + (-1 % 10) = 9)
index + array.Length + (shiftCount % array.Length) % array.Length
-> 두번째 정규화 (normalization) 를 통해 새로운 인덱스 값이 배열이 범위를 벗어나지 않고 배열의 앞쪽으로 rotate될 수 있도록 한다. 이는 우측으로 rotate 되는 경우를 위함으로, 이 코드가 없다면 배열의 크기가 10
이고 shift 시킬 값이 1
인 상황에서 index
가 9
가 될 경우 새로운 인덱스 값은 10
이 될 것이며 실제로 필요한 인덱스 값인 0
을 계산해내지 못할 것이다. ((9 + 10 + (1 % 10)) % 10 = 0)
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.
[출처] https://books.goalkicker.com/CSharpBook/
'번역 > C# Notes for Professionals' 카테고리의 다른 글
22.1: Enum 에 대한 기본 사항들 (0) | 2021.05.12 |
---|---|
22: Enum (0) | 2021.05.12 |
20.12: 하나의 배열이 다른 배열의 내용을 포함하고 있는지 검사하기 (0) | 2021.05.10 |
20.11: IEnumerable<> 인스턴스로의 배열 (0) | 2021.05.10 |
20.10: 배열 공변성 (covariance) (0) | 2021.05.01 |