#문제
https://programmers.co.kr/learn/courses/30/lessons/17677
#풀이
1. 각 문자열을 두 문자씩 쪼개서 Map<String, Integer>에 넣는다. 이때 value값은 해당 문자가 나온 횟수이다.
- 정규식을 이용해 특수문자가 포함된 문자를 필터링한다.
- 이 때 원소의 총 개수를 count한다.
2. 교집합의 개수를 구한다.
- 둘 중 하나의 맵을 순회하면서 다른 맵의 동일한 key가 있는지 체크하여, 동일한 key가 있으면 value의 Min값의 합을 구한다.
3. 합집합의 원소를 구한다.
- 전체 원소 개수 - 교집합 원소 개수
- 합집합이 공집합일 경우 65536 리턴한다.
- 이 외 케이스는 자카드 유사도 계산하여 리턴한다.
Java 정규식에서 영문자 이외에 모든 문자를 제거하고 싶을 때는 [^A-Za-z] 괄호 안에 ^ 기호를 붙여서 사용한다.
괄호 밖에 있으면 첫번째 등장하는 조건이니 유의해야한다.
#소스코드
import java.util.*;
import java.util.regex.*;
class Solution {
public HashMap<String, Integer> map1, map2;
public int solution(String str1, String str2) {
int answer = 0;
map1 = new HashMap<String, Integer>();
map2 = new HashMap<String, Integer>();
str1 = str1.toUpperCase();
str2 = str2.toUpperCase();
Pattern p = Pattern.compile("[^A-Za-z]");
Matcher m = null;
int totalCnt = 0;
for(int i = 0; i <= str1.length()-2; i++){
String key = str1.substring(i, i+2);
m = p.matcher(key);
if(m.find()) continue;
map1.put(key, map1.getOrDefault(key, 0) + 1);
totalCnt++;
}
for(int i = 0; i <= str2.length()-2; i++){
String key = str2.substring(i, i+2);
m = p.matcher(key);
if(m.find()) continue;
map2.put(key, map2.getOrDefault(key, 0) + 1);
totalCnt++;
}
int interCnt = 0;
for(String key : map1.keySet()){
if(map2.get(key) == null) continue;
interCnt += Math.min(map2.get(key), map1.get(key));
}
int unionCnt = totalCnt - interCnt;
if(unionCnt == 0) return 65536;
return interCnt*65536/unionCnt;
}
}
'💡Problem Solving > Programmers' 카테고리의 다른 글
[프로그래머스] 프렌즈4블록 (Java) (0) | 2021.10.23 |
---|---|
[프로그래머스] 게임 맵 최단거리 (Java) (0) | 2021.10.23 |
[프로그래머스] 소수 찾기 (Java) (0) | 2021.10.23 |
[프로그래머스] JadenCase 문자열 만들기 (Java) (0) | 2021.10.23 |
[프로그래머스] 오픈채팅방 (Java) (0) | 2021.10.22 |