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 인 배열에 대해서 index0 이고 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 인 상황에서 index9 가 될 경우 새로운 인덱스 값은 10 이 될 것이며 실제로 필요한 인덱스 값인 0 을 계산해내지 못할 것이다. ((9 + 10 + (1 % 10)) % 10 = 0)

본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

+ Recent posts