카테고리 없음
[BOJ] 14단계 집합과 맵
kinggora
2023. 4. 9. 00:08
집합(Set), 맵(Map)
특정 원소가 속해 있는지 빠르게 찾거나, 각 원소에 대응되는 원소를 빠르게 찾는 자료구조
| 1 | 10815 | 숫자 카드 |
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(reader.readLine());
StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
Set<String> set = new HashSet<>();
for(int i = 0; i < N; i++) {
set.add(tokenizer.nextToken());
}
int M = Integer.parseInt(reader.readLine());
tokenizer = new StringTokenizer(reader.readLine());
StringBuilder sb = new StringBuilder();
for(int i = 0; i < M; i++) {
if(set.contains(tokenizer.nextToken())) {
sb.append(1).append(" ");
} else {
sb.append(0).append(" ");
}
}
System.out.println(sb);
}
}
*같은 로직을 List로 적용하면 시간 초과 발생 (대신 메모리는 더 적게 사용)
*Contains: List -> O(n), Set&Map -> O(1) (트리 구조는 O(log n))
| 2 | 14425 | 문자열 집합 |
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
int N = Integer.parseInt(tokenizer.nextToken());
int M = Integer.parseInt(tokenizer.nextToken());
Set<String> set = new HashSet<>();
for(int i = 0; i < N; i++) {
set.add(reader.readLine());
}
int cnt = 0;
for(int i = 0; i < M; i++) {
if(set.contains(reader.readLine())){
cnt++;
}
}
System.out.println(cnt);
}
}
| 3 | 7785 | 회사에 있는 사람 |
빠른 탐색(contains) -> 정렬(sort)
1. TreeSet
add, remove 시 정렬된 상태로 데이터 유지. 생성자에 Comparator 지정 가능
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(reader.readLine());
Set<String> company = new TreeSet<>(Collections.reverseOrder());
for(int i = 0; i < n; i++) {
String[] split = reader.readLine().split(" ");
if(split[1].equals("enter")) {
company.add(split[0]);
} else if(split[1].equals("leave")) {
company.remove(split[0]);
}
}
for(String employee: company) {
System.out.println(employee);
}
}
}
2. HashSet -> ArrayList
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(reader.readLine());
Set<String> companySet = new HashSet<>();
for(int i = 0; i < n; i++) {
String[] split = reader.readLine().split(" ");
if(split[1].equals("enter")) {
companySet.add(split[0]);
} else if(split[1].equals("leave")) {
companySet.remove(split[0]);
}
}
List<String> companyList = new ArrayList<>(companySet);
companyList.sort(Collections.reverseOrder());
for(String employee: companyList) {
System.out.println(employee);
}
}
}
| 4 | 1620 | 나는야 포켓몬 마스터 이다솜 |
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] split = reader.readLine().split(" ");
int N = Integer.parseInt(split[0]);
int M = Integer.parseInt(split[1]);
Map<String, String> pokedex = new HashMap<>();
for(int i = 1; i <= N; i++) {
String num = String.valueOf(i);
String poketmon = reader.readLine();
pokedex.put(num, poketmon);
pokedex.put(poketmon, num);
}
StringBuilder sb = new StringBuilder();
for(int i = 0; i < M; i++) {
sb.append(pokedex.get(reader.readLine())).append("\n");
}
System.out.print(sb);
}
}
*양방향으로 데이터를 Map에 추가하여 어떤 키로 접근해도 O(1)로 접근할 수 있도록 한다.
| 5 | 10816 | 숫자 카드 2 |
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(reader.readLine());
StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
Map<String, Integer> cardCount = new HashMap<>();
for(int i = 0; i < N; i++) {
String cardNum = tokenizer.nextToken();
if(cardCount.containsKey(cardNum)) {
cardCount.put(cardNum, cardCount.get(cardNum) + 1);
} else {
cardCount.put(cardNum, 1);
}
}
int M = Integer.parseInt(reader.readLine());
tokenizer = new StringTokenizer(reader.readLine());
StringBuilder sb = new StringBuilder();
for(int i = 0; i < M; i++) {
String cardNum = tokenizer.nextToken();
if(cardCount.containsKey(cardNum)) {
sb.append(cardCount.get(cardNum));
} else {
sb.append(0);
}
sb.append(" ");
}
System.out.print(sb);
}
}
*숫자 카드의 범위가 -10,000,000 ~ 10,000,000 이므로 일반 카운팅 정렬 사용 불가
*해시맵 또는 이진 탐색을 사용해야 함
| 6 | 1764 | 듣보잡 |
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
int N = Integer.parseInt(tokenizer.nextToken());
int M = Integer.parseInt(tokenizer.nextToken());
Set<String> set = new HashSet<>();
for(int i = 0; i < N; i++) {
set.add(reader.readLine());
}
List<String> list = new ArrayList<>();
for(int i = 0; i < M; i++) {
String s = reader.readLine();
if(set.contains(s)) {
list.add(s);
}
}
Collections.sort(list);
System.out.println(list.size());
for(int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
*원소 포함 여부 -> Set, 정렬 -> List
| 7 | 1269 | 대칭 차집합 |
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
int A = Integer.parseInt(tokenizer.nextToken());
int B = Integer.parseInt(tokenizer.nextToken());
tokenizer = new StringTokenizer(reader.readLine());
Set<String> diffAB = new HashSet<>();
for(int i = 0; i < A; i++) {
diffAB.add(tokenizer.nextToken());
}
tokenizer = new StringTokenizer(reader.readLine());
Set<String> diffBA = new HashSet<>();
for(int i = 0; i < B; i++) {
String element = tokenizer.nextToken();
if(diffAB.contains(element)) {
//집합 A에서 A,B 공통 원소 제거
diffAB.remove(element);
} else {
//집합 B에만 있는 원소 추가
diffBA.add(element);
}
}
System.out.println(diffAB.size() + diffBA.size());
}
}
| 8 | 11478 | 서로 다른 부분 문자열의 개수 |
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str = reader.readLine();
Set<String> substrings = new HashSet<>();
for(int i = 0; i < str.length(); i++) {
for(int j = i + 1; j <= str.length(); j++) {
substrings.add(str.substring(i, j));
}
}
System.out.println(substrings.size());
}
}
*String.substring(i, j): index i번째 부터 j-1번째 문자열 반환