듣지 못한 사람 N명이 나오고, 보지 못한 사람 M명이 나온다.
이 때 듣지도 못했고 보지도 못했던 사람을 고르는 문제이다.
즉, 2개의 String 배열이 주어지고, 2개 배열에 동시에 존재하는 사람을 찾아 출력한다
이 때 2개 배열에 동시에 존재하는 사람을 사전순으로 출력한다.
이전에 풀었던 수 찾기의 String 버전이다.
따라서 먼저 나온 N명의 듣지 못한 사람을 배열에 저장할 것이다.
이후 보지 못한 사람을 한 명씩 입력받고, 해당 사람 이름이 배열에 존재하는지 여부를 확인하면 될 것이다.
이 때, left와 right를 어떻게 해야할지 생각해야 한다.
String 배열을 Arrays.sort로 Sorting할 경우 (ASCII코드 기준) 사전 순으로 정렬된다.
A.compareTo(B) 값의 결과는 아래와 같다.
내가 찾고 싶은 문자열이 A일 경우, B.compareTo(A) > 0 라면 B가 A보다 사전순으로 뒤에 있다는 의미이므로 B가 존재하는 index 이전 위치만 찾으면 된다. 즉 right값을 변경해준다.
음수일 경우 반대이므로, left 값을 변경해준다.
import java.util.*;
public class Main {
static int N;
static String[] arr;
static Boolean bin_search(String str) {
// 이분 탐색 함수
int left = 0;
int right = N -1;
int mid;
while(left <= right) {
mid = (left + right) / 2;
if(arr[mid].compareTo(str)>0) {
// arr[mid]가 str보다 뒤에 존재함
// mid보다 왼쪽만 Search하면 되기 때문에 right = mid - 1로 설정
right = mid - 1;
}
else if(arr[mid].compareTo(str)<0) {
// arr[mid]가 str보다 앞에 존재함
// mid보다 오른쪽만 Search하면 되기 때문에 left = mid + 1로 설정
left = mid + 1;
}
else {
// str과 똑같은 값이 array에 존재함
// True를 반환 후 함수 종료
return true;
}
}
// while문을 빠져나왔다는 의미는 str과 똑같은 값이 array에
// 존재하지 않음을 의미한다. 따라서 False를 반환한다.
return false;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
int M = sc.nextInt();
arr = new String[N];
sc.nextLine();
for(int i = 0;i<N;i++) {
arr[i] = sc.nextLine();
}
Arrays.sort(arr); // 이분 탐색의 핵심 : 배열의 Sorting!!!
String str;
StringBuilder sb = new StringBuilder();
String[] ans = new String[N];
int answer = 0;
for(int i =0;i<M;i++) {
str = sc.nextLine();
if(bin_search(str)) {
// bin_search(str) = true일 경우 해당 값이 배열에
// 존재한다는 의미이다. 배열에 이름 저장 & 개수 1 증가시킨다
ans[answer] = str;
answer++;
}
}
Arrays.sort(ans, 0, answer);
// 2개 배열에 동시에 존재하는 값을 정렬한 이후 출력해야 한다.
// 0 ~ (answer-1) index 공간에만 이름이 저장되어 있기 때문에
// 이 부분만 Sorting 시킨다.
sb.append(answer+"\n");
for(int i=0;i<answer;i++) {
sb.append(ans[i]+"\n");
}
System.out.println(sb);
}
}