해당 문제는 객체 정렬을 이용하는 문제인데요. 저에게 있어서 객체 문제 자체를 푸는건 이번이 처음이였기도 했지만, 평소에 객체를 잘 사용하지 않은 상태에서 접했다보니 긴장감도 있었는데요. 그래도 객체를 익히는 면에서는 꽤 도움이 되었던 것 같다고 생각되는 만큼, 배열만 사용해오던 저에게는 의미 있는 시간이기도 했답니다.
아무튼 해당 문제는 다음과 같은 과정을 거치게 되는데요.
특히 이번 문제는 다른 분들 문제 풀이를 보면서 정렬을 이용하여 푸신 분들이 꽤 되셨다는걸 알았는데요. 저는 정렬을 사용하긴 했는데 위치를 찾아내는 방법은 정렬을 이용하기 보다는 name 프로퍼티를 활용했다보니 "아 이렇게도 풀 수 있구나" 싶었답니다.
그럼 해당 문제 풀이에 대한 알고리즘을 이미지로 보여드리도록 하겠습니다.
그럼 다음으로 해당 문제 풀이 코드를 JS 버전으로 소개해 드리겠습니다.
- 자바스크립트 버전
const fs = require('fs'); const input = fs.readFileSync('/dev/stdin').toString().trim().split("\n"); let [length, arr] = [input.shift(), input] arr = arr[0].split(" ").map(Number); // 각 배열에 생성해 줄 객체들 class Num{ // 번호를 매길 공유 자원 static num = 1; // 프로퍼티들 constructor(name){ this.name = name; this.num = Num.num++; } } // 원본 배열과 정렬된 원본 배열에 대한 각각의 복사 배열들 let originalArr = []; let sortedArr = []; // 원본 배열 복사본 만들기 arr.forEach(item => { originalArr.push(new Num(item)) }) // 공통 자원 1로 초기화 Num.num = 1; // 정렬된 원본 배열 복사본 만들기 arr.sort((a,b) => { return a - b }).forEach(item => { sortedArr.push(new Num(item)) }) // 2중 for문을 돌리고 대응되는 name을 찾을 때 position 값을 원본 배열 복사본의 // 해당 요소에 할당하고 정렬된 원본 배열 복사본의 해당 객체를 삭제 후 break(더 도는건 손해) for(let i = 0 ; i < originalArr.length ; i++){ for(let j = 0 ; j < originalArr.length ; j++){ if(originalArr[i].name === sortedArr[j].name){ originalArr[i].num = sortedArr[j].num sortedArr.splice(j,1); break; } } } // 작업이 끝난 뒤 원본 배열 중 각 요소들의 num 들만 담은 배열 반환 받고 join으로 합친 뒤 출력. const result = originalArr.map(item => item.num) console.log(result.join(" "));
그리고 자바 버전으로 구현한 코드는 다음과 같습니다.
import java.util.*; class Num { static int itemNumber = 1; int name; int num; Num(int name) { this.name = name; this.num = Num.itemNumber++; } // 디버깅용 오버라이딩 toString @Override public String toString() { return "Num{name=" + name + ", num=" + num + "}"; } } public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int length = Integer.parseInt(scanner.nextLine().trim()); String[] input = scanner.nextLine().trim().split(" "); List<Num> originalArr = new ArrayList<>(); List<Num> sortedArr = new ArrayList<>(); // 원본 배열 복사본 만들기 for (int i = 0; i < length; i++) { int value = Integer.parseInt(input[i].trim()); originalArr.add(new Num(value)); } // 공통 자원 1로 초기화 Num.itemNumber = 1; // 입력 값을 정렬하여 정렬된 원본 배열 복사본 만들기 // input을 스트림으로 만든 뒤 int 스트림으로 변환해주고 sorted로 정렬한 후 스트림을 배열로 변환 int[] sortedValues = Arrays.stream(input) .mapToInt(Integer::parseInt) .sorted() .toArray(); for (int value : sortedValues) { sortedArr.add(new Num(value)); } // 2중 for문을 돌리고 대응되는 name을 찾을 때 position 값을 원본 배열 복사본의 // 해당 요소에 할당하고 정렬된 원본 배열 복사본의 해당 객체를 삭제 후 break(더 도는건 손해) for (int i = 0; i < originalArr.size(); i++) { for (int j = 0; j < sortedArr.size(); j++) { if (originalArr.get(i).name == sortedArr.get(j).name) { originalArr.get(i).num = sortedArr.get(j).num; sortedArr.remove(j); break; } } } // 작업이 끝난 뒤 원본 배열 중 각 요소들의 num 들만 담은 배열 반환 받고 join으로 합친 뒤 출력. int[] result = new int[length]; for (int i = 0; i < originalArr.size(); i++) { result[i] = originalArr.get(i).num; } System.out.println(Arrays.toString(result).replaceAll("[\\[\\],]", "")); } }
2주차에 접어들면서 슬슬 프로그래밍 연습 파트에 들어갔는데 그래도 올라가는 그래프를 보면 흐뭇하기도 합니다...!