백준 1181번: 단어 정렬

kgh128·2023년 1월 30일

코드: https://github.com/kgh128/Problem-Solving/blob/main/src/Baekjoon/p1181.java


1. 중복 단어 제거

HashSet 클래스를 이용하여 중복 단어를 제거한다. 입력받은 단어를 바로 HashSet 객체인wordSet에 넣는다. HashSet은 중복을 허용하지 않기 때문에 같은 단어가 여러번 들어와도 wordSet 안에는 한 개만 저장된다.

import java.util.HashSet;

// HashSet 객체 생성
HashSet<String> set = new HashSet<>();
HashSet<String> set = new HashSet<>(3); // 원소를 3개 가짐.

// HashSet에 값 추가
set.add("value");

// HashSet 내용 출력
// HashSet은 삽입 시 순서가 존재하지 않으므로 Iterator를 통해 값을 가져와야 한다.
// (순서가 없다기보다는 보장하지 않는다는 의미이고, 대부분 넣은 값의 hashCode에 따라 순서대로 나온다.)
Iterator<String> iterator = set.Iterator();
while(iterator.hasNext()) {
	iterator.next();
}

// HashSet 크기
set.size();

2. 단어 정렬

  • 길이가 짧은 것부터 (오름차순)
  • 길이가 같으면 사전 순으로 (오름차순)

위의 조건들에 맞게 단어를 정렬한다. "1. 중복 단어 제거"에서 설명하였듯이 HashSet은 순서를 보장하지 않으므로 이 자료구조에서 바로 정렬할 수는 없다. 따라서 HashSet을 순서가 존재하여 정렬할 수 있는 ArrayList로 변환한다.

ArrayList<String> wordList = new ArrayList<>(wordSet);

그리고 sort()를 이용하여 정렬하는데, 위의 조건들은 기존 sort()의 정렬 기준과 맞지 않으므로 위의 조건에 맞게 Comparator를 만들어서 sort()의 인자로 전달한다. 그리하면 원하는대로 wordList가 정렬된다.

Comparatorcompare() 메소드를 이용하여 특별한 조건을 가진 정렬을 구현하기 위한 인터페이스이다. compare() 메소드는 양수가 리턴되면 두 매개변수의 위치를 뒤바꾼다. Comparator를 만든다는 것은 정확히 말하면 compare() 함수를 구현하는 것이다. 매개변수가 a, b라 했을 때 오름차순으로 정렬하려면 다음과 같이 리턴하도록 해야 한다.

  • a < b : 위치 변화X여야 함. -> 음수 리턴
  • a > b : 위치 변화O여야 함. -> 양수 리턴

return a - b를 하면 된다. 내림차순 정렬은 반대로 return b - a를 하면 된다.

Comparator를 만들 때(compare()를 구현할 때)는 람다(익명 함수)를 이용한다.

  • 람다는 매개변수 -> 함수 구현부로 사용
  • 함수 구현부가 단일 실행문이면 중괄호 생략 가능
  • 함수 구현부return문으로만 구성되어 있는 경우 중괄호 생략 불가능
Comparator<String> comparator = (a, b) -> {
	if (a.length() == b.length()) {
		return a.compareTo(b);
	}
	return a.length() - b.length();
};

wordList.sort(comparator);

길이가 짧은 것이 앞에 온다라는 조건만 생각하고 두번째 조건은 생각안해서 테스트 케이스 돌려봤을 때 잘못된 결과가 나왔다. 문제를 먼저 꼼꼼히 읽자.


3. 결과 출력

중복을 제거하고 정렬한 단어 리스트를 반복문을 통해 출력 버퍼에 넣는다. 이때, 향상된 for문을 이용한다. 그리고 버퍼에 있는 내용을 출력한다.

for (String word: wordList) {
	bw.append(word).append('\n');
}
System.out.print(bw);
}

0개의 댓글