<문제 제시>
<문제설명>
알파벳 소문자로 이루어진 N개의 단어가 들어오면 아래와 같은 조건에 따라 정렬하는 프로그램을 작성하시오.
길이가 짧은 것부터
길이가 같으면 사전 순으로
단, 중복된 단어는 하나만 남기고 제거해야 한다.
<예시 입출력>
<문제 해결 과정>
사전 프로그램을 만드는 문제이다. 대신 조건이 두가지있는데, 마냥 내림차순, 오름차순 정렬을 하는 것이 아닌
1. 길이가 짧은 것부터 우선순위
2. 그 후 길이가 같으면 사전순으로
조건을 어떻게 맞춰야할지 막막하기도 했다.
Try 1)
HashSet<String> remove = new HashSet<>();
List<String> input = new ArrayList<>();
// 1. 중복제거를 위해 HashSet에 값을 대입
for(int i = 0; i < N; i++) {
remove.add(br.readLine());
}
// 2. 따라서 입력된 단어들의 길이를 하나하나 비교해봐야하므로, String List에 옮겨담는 과정
Iterator iter = remove.iterator(); // Iterator 사용
while(iter.hasNext()) {
input.add((String) iter.next());
}
// 3. 단어의 길이에 따라 정렬
List<String> temp = new ArrayList<>();
int min = 0;
for(int i = 0; i < input.size(); i++) {
int length = input.get(i).length();
}
모든 조건을 하나하나 만들어보기로하였다. 하지만 통과할 수 없었다.
- Set 자료구조는 인덱스로 객체를 가져오는 get(index) 메소드가 없어 데이터를 참조할 수 없었다.
- 대신 전체 객체를 대상으로 한 번씩 반복해서 가져오는 반복자(Iterator)를 통해 구할 수 있었다. Set을 iterator()로
반복자를 만들 수 있었다.
// 반복자 : 이터레이터 인터페이스를 구현한 객체를 말하는데 iterator() 메소드를 호출해서 사용
- Iterator에서 하나의 객체를 가져올 때는 next() 메소드를 사용 (데이터를 가져오는 메서드 사용 가능해짐)
// next() 메소드를 사용하기 전에 먼저 가져올 객체가 있는지 확인 >> hasNext() (값이 있어야 가져올 수 있으므로)
// hasNext() 메소드는 가져올 객체가 있으면 true, 없으면 false를 리턴
하지만 3번에서
각 길이를 비교해서 정렬하고 싶었지만,
단어의 길이를 토대로 정렬하여도 그 인덱스의 단어또한 정렬할 순 없었다.
Answer 1)
// Comparator 클래스를 오버라이딩하여 사용한다.
Arrays.sort(temp, new Comparator<String>() {
public int compare(String s1, String s2) {
// 1) 단어 길이가 같을 경우
if(s1.length() == s2.length()) {
return s1.compareTo(s2);
}
else {
return s1.length() - s2.length();
}
}
});
Comparator 클래스를 오버라이딩하는데, new Comparator<String>() 으로 가져온다.
s1, s2의 오브젝트를 두고, 그 두 단어의 길이가 같을 경우 0을 반환
s1 > s2 일 경우 1반환
s1 < s2 일 경우 -1반환
여기서는 else로 s1-s2의 차감값을 반환한다.
그 후
sb.append(temp[0]).append('\n');
// 첫요소는 넣고 시작
// 중복제거
for(int i = 1; i < N; i++) {
// 중복되지 않는 단어만 출력
if(!temp[i].equals(temp[i - 1])) {
// temp[i]를 넣으면서 줄바꿈
sb.append(temp[i]).append('\n');
}
}
처럼 배열 안에 중복되는 단어가있는지 체크한다.
끝값에서 인덱스 참조를 위해 첫값은 미리 StringBuilder에 넣고, i부터 i-1와 비교해가며 StringBuilder에 누적시킨다.
<전체코드>
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
String[] temp = new String[N];
for(int i = 0; i < N; i++) {
temp[i] = br.readLine();
}
// Comparator 클래스를 오버라이딩하여 사용한다.
Arrays.sort(temp, new Comparator<String>() {
public int compare(String s1, String s2) {
// 1) 단어 길이가 같을 경우
if(s1.length() == s2.length()) {
return s1.compareTo(s2);
}
else {
return s1.length() - s2.length();
}
}
});
StringBuilder sb = new StringBuilder();
sb.append(temp[0]).append('\n');
// 첫요소는 넣고 시작
// 중복제거
for(int i = 1; i < N; i++) {
// 중복되지 않는 단어만 출력
if(!temp[i].equals(temp[i - 1])) {
// temp[i]를 넣으면서 줄바꿈
sb.append(temp[i]).append('\n');
}
}
System.out.println(sb);
}
}
Comparator 클래스를 오버라이딩해서 사용하는 부분과, s1.compareTo(s2)를 했을 경우 반환값을 판단하는 부분,
중복 체크를 위해 i와 i-1인덱스를 비교하는 부분등을 공부할 수 있었다.
문제링크)
https://www.acmicpc.net/problem/1181
'Algorithms > 백준' 카테고리의 다른 글
[백준] '행렬 덧셈' - Java (0) | 2023.07.16 |
---|---|
[백준] '나이순 정렬' - Java (0) | 2023.07.15 |
[백준] '소트인사이드' - Java (0) | 2023.07.14 |
[백준] '골드바흐의 추측' - Java (0) | 2023.05.19 |
[백준] '과제 안 내신 분..?' - Java (0) | 2023.05.18 |