-
[JAVA] 배열 회전하기Java/Collection(컬렉션) 2024. 9. 17. 16:52반응형
목차
자바에서는 배열을 회전시키는 여러 가지 방법이 있습니다. 전통적인 for 문, 스트림 API, 그리고 헬퍼 메서드를 사용하는 방법이 있습니다.
1. 반복문을 사용하여 배열을 회전
전통적인 for 문를 사용하여 배열을 회전하는 방법은 직관적이고 간단합니다.
/** * 반복문을 사용하여 배열을 회전 * * @param nums 회전할 배열 * @param k 회전할 위치 수 * @return 회전된 배열 */ public int[] rotateWithLoop(int[] nums, int k) { int n = nums.length; if (n == 0) { return nums; } k = k % n; int[] rotated = new int[n]; for (int i = 0; i < n; i++) { rotated[(i + k) % n] = nums[i]; } return rotated; }
단위 테스트
@Order(1) @DisplayName("rotateWithLoop: 배열 회전") @Test void testRotateWithLoop() { // Given int[] nums = {1, 2, 3, 4, 5, 6, 7}; // When int[] result = arrayRotation.rotateWithLoop(nums, 3); // Then int[] expected = {5, 6, 7, 1, 2, 3, 4}; assertArrayEquals(expected, result); } @Order(2) @DisplayName("rotateWithLoop: 빈 배열 테스트") @Test void testRotateWithLoopEmptyArray() { // Given int[] nums = {}; // When int[] result = arrayRotation.rotateWithLoop(nums, 3); // Then int[] expected = {}; assertArrayEquals(expected, result); } @Order(3) @DisplayName("rotateWithLoop: 단일 요소 배열 회전") @Test void testRotateWithLoopSingleElement() { // Given int[] nums = {1}; // When int[] result = arrayRotation.rotateWithLoop(nums, 3); // Then int[] expected = {1}; assertArrayEquals(expected, result); } @Order(4) @DisplayName("rotateWithLoop: 회전을 하지 않는 경우 테스트") @Test void testRotateWithLoopZeroTimes() { // Given int[] nums = {1, 2, 3, 4, 5, 6, 7}; // When int[] result = arrayRotation.rotateWithLoop(nums, 0); // Then int[] expected = {1, 2, 3, 4, 5, 6, 7}; assertArrayEquals(expected, result); } @Order(5) @DisplayName("rotateWithLoop: 배열 길이보다 많은 회전 테스트") @Test void testRotateWithLoopMoreThanLength() { // Given int[] nums = {1, 2, 3, 4, 5, 6, 7}; // When int[] result = arrayRotation.rotateWithLoop(nums, 10); // Then int[] expected = {5, 6, 7, 1, 2, 3, 4}; assertArrayEquals(expected, result); }
장점
- 직관성 : 단순하고 이해하기 쉽습니다.
단점
- 코드 길이 : 더 복잡한 경우 코드가 길어질 수 있습니다.2. Stream API를 사용하여 배열을 회전
Java 8부터 도입된 스트림 API를 사용하면 더 간결하고 함수형 프로그래밍 스타일의 코드를 작성할 수 있습니다.
/** * 스트림을 사용하여 배열을 회전 * * @param nums 회전할 배열 * @param k 회전할 위치 수 * @return 회전된 배열 */ public int[] rotateWithStreams(int[] nums, int k) { int n = nums.length; if (n == 0) { return nums; } k = k % n; final int finalK = k; return IntStream.range(0, n) .map(i -> nums[(i + (n - finalK)) % n]) .toArray(); }
단위 테스트
@Order(6) @DisplayName("rotateWithStreams: 배열 회전") @Test void testRotateWithStreams() { // Given int[] nums = {1, 2, 3, 4, 5, 6, 7}; // When int[] result = arrayRotation.rotateWithStreams(nums, 3); // Then int[] expected = {5, 6, 7, 1, 2, 3, 4}; assertArrayEquals(expected, result); } @Order(7) @DisplayName("rotateWithStreams: 빈 배열 테스트") @Test void testRotateWithStreamsEmptyArray() { // Given int[] nums = {}; // When int[] result = arrayRotation.rotateWithStreams(nums, 3); // Then int[] expected = {}; assertArrayEquals(expected, result); } @Order(8) @DisplayName("rotateWithStreams: 단일 요소 배열 회전") @Test void testRotateWithStreamsSingleElement() { // Given int[] nums = {1}; // When int[] result = arrayRotation.rotateWithStreams(nums, 3); // Then int[] expected = {1}; assertArrayEquals(expected, result); } @Order(9) @DisplayName("rotateWithStreams: 회전을 하지 않는 경우 테스트") @Test void testRotateWithStreamsZeroTimes() { // Given int[] nums = {1, 2, 3, 4, 5, 6, 7}; // When int[] result = arrayRotation.rotateWithStreams(nums, 0); // Then int[] expected = {1, 2, 3, 4, 5, 6, 7}; assertArrayEquals(expected, result); } @Order(10) @DisplayName("rotateWithStreams: 배열 길이보다 많은 회전 테스트") @Test void testRotateWithStreamsMoreThanLength() { // Given int[] nums = {1, 2, 3, 4, 5, 6, 7}; // When int[] result = arrayRotation.rotateWithStreams(nums, 10); // Then int[] expected = {5, 6, 7, 1, 2, 3, 4}; assertArrayEquals(expected, result); }
장점
- 가독성 : 코드가 매우 간결하고 읽기 쉽습니다.
- 함수형 프로그래밍 : 최신 자바에서 선호되는 함수형 프로그래밍 패러다임을 활용합니다.
단점 :
- 성능 오버헤드 : 스트림은 약간의 성능 오버헤드를 수반할 수 있습니다.3. 헬퍼 메서드를 사용하여 배열을 회전
헬퍼 메서드를 사용하여 배열을 회전시키는 방법은 배열을 역순으로 뒤집어 회전 효과를 얻을 수 있습니다.
/** * 헬퍼 메서드를 사용하여 배열을 회전시킵니다. 배열을 역순으로 뒤집는 방법을 사용 * * @param nums 회전할 배열 * @param k 회전할 위치 수 * @return 회전된 배열 */ public int[] rotateWithHelperMethods(int[] nums, int k) { int n = nums.length; if (n == 0) { return nums; } k = k % n; int[] result = nums.clone(); reverse(result, 0, n - 1); reverse(result, 0, k - 1); reverse(result, k, n - 1); return result; } /** * 배열의 일부를 뒤집는 헬퍼 메서드 * * @param nums 회전할 배열 * @param start 뒤집을 시작 인덱스 * @param end 뒤집을 끝 인덱스 */ private void reverse(int[] nums, int start, int end) { while (start < end) { int temp = nums[start]; nums[start] = nums[end]; nums[end] = temp; start++; end--; } }
단위 테스트
@Order(11) @DisplayName("rotateWithHelperMethods: 배열 회전") @Test void testRotateWithHelperMethodsBasic() { // Given int[] nums = {1, 2, 3, 4, 5, 6, 7}; // When int[] result = arrayRotation.rotateWithHelperMethods(nums, 3); // Then int[] expected = {5, 6, 7, 1, 2, 3, 4}; assertArrayEquals(expected, result); } @Order(12) @DisplayName("rotateWithHelperMethods: 빈 배열 테스트") @Test void testRotateWithHelperMethodsEmptyArray() { // Given int[] nums = {}; // When int[] result = arrayRotation.rotateWithHelperMethods(nums, 3); // Then int[] expected = {}; assertArrayEquals(expected, result); } @Order(13) @DisplayName("rotateWithHelperMethods: 단일 요소 배열 회전") @Test void testRotateWithHelperMethodsSingleElement() { // Given int[] nums = {1}; // When int[] result = arrayRotation.rotateWithHelperMethods(nums.clone(), 3); // Then int[] expected = {1}; assertArrayEquals(expected, result); } @Order(14) @DisplayName("rotateWithHelperMethods: 회전을 하지 않는 경우 테스트") @Test void testRotateWithHelperMethodsZeroTimes() { // Given int[] nums = {1, 2, 3, 4, 5, 6, 7}; // When int[] result = arrayRotation.rotateWithHelperMethods(nums.clone(), 0); // Then int[] expected = {1, 2, 3, 4, 5, 6, 7}; assertArrayEquals(expected, result); } @Order(15) @DisplayName("rotateWithHelperMethods: 배열 길이보다 많은 회전 테스트") @Test void testRotateWithHelperMethodsMoreThanLength() { // Given int[] nums = {1, 2, 3, 4, 5, 6, 7}; // When int[] result = arrayRotation.rotateWithHelperMethods(nums.clone(), 10); // Then int[] expected = {5, 6, 7, 1, 2, 3, 4}; assertArrayEquals(expected, result); }
장점
- 효율성 : 추가 배열 저장소 없이 배열 회전이 가능합니다.
단점
- 복잡성 : 세 단계로 배열을 뒤집어야 하므로 직관적이지 않을 수 있습니다.결론
결론적으로, 자바에서 배열 회전을 구현하는 방법은 다양합니다. 상황에 따라 가장 적합한 방법을 선택하여 사용할 수 있습니다. 일반적으로 스트림 API는 간결성과 가독성 측면에서 많이 선호되며, 전통적인 for 문 또한 여전히 널리 사용됩니다. 더 복잡한 회전 로직이 필요한 경우 헬퍼 메서드를 사용하는 것이 효율적일 수 있습니다.
소스 코드는 Github Repository- https://github.com/tychejin1218/blog/tree/main/java-collection 프로젝트를 참조하세요.
반응형'Java > Collection(컬렉션)' 카테고리의 다른 글
[JAVA] 리스트 정렬하기 : 오름차순, 내림차순, 병렬 정렬 (0) 2024.09.27 [JAVA] 배열의 중복 요소 제거하기 (2) 2024.09.17 [JAVA] 배열의 합 구하기 (1) 2024.09.17 [JAVA] 배열 검색하기 (0) 2024.09.17 [JAVA] 배열 정렬하기 : 오름차순, 내림차순 (1) 2024.09.17