728x90
문제
https://programmers.co.kr/learn/courses/30/lessons/17677
내 풀이
import java.util.*;
import java.util.Map.Entry;
class Solution {
public int solution(String str1, String str2) {
int answer = 0;
str1 = str1.toLowerCase();
str2 = str2.toLowerCase();
// 교 - 민
double intersectionCount = intersection(str1, str2);
// 합 - 맥
double unionCount = union(str1, str2);
double similar = 0;
if(intersectionCount == 0 && unionCount == 0) {
similar = 1;
} else {
similar = intersectionCount / unionCount;
}
return (int) Math.floor(similar * 65536);
}
private double intersection(String str1, String str2) {
Map<String, Integer> records = getRecords(str1);
double count = 0;
for (int i=0; i<str2.length()-1; i++) {
char c1 = str2.charAt(i);
char c2 = str2.charAt(i+1);
if (isAlphabet(c1, c2)) {
String key = str2.substring(i, i+2);
if (records.containsKey(key)) {
if (records.get(key) == 1) {
records.remove(key);
} else {
records.put(key, records.get(key) - 1);
}
count++;
}
}
}
return count;
}
private double union(String str1, String str2) {
Map<String,Integer> records1 = getRecords(str1);
Map<String,Integer> records2 = getRecords(str2);
double count = 0;
for (Entry<String, Integer> entry : records1.entrySet()) {
if (records2.containsKey(entry.getKey())) {
count += Math.max(entry.getValue(), records2.get(entry.getKey()));
records2.remove(entry.getKey());
} else {
count += entry.getValue();
}
}
for (Entry<String, Integer> entry : records2.entrySet()) {
count += entry.getValue();
}
return count;
}
private Map<String,Integer> getRecords(String str1) {
Map<String, Integer> records = new HashMap<>();
for(int i=0; i<str1.length()-1; i++) {
char c1 = str1.charAt(i);
char c2 = str1.charAt(i+1);
if (isAlphabet(c1, c2)) {
String key = str1.substring(i, i+2);
records.put(key, records.getOrDefault(key, 0) + 1);
}
}
return records;
}
private boolean isAlphabet(char c1, char c2) {
return ('a' <= c1 && c1 <= 'z') && ('a' <= c2 && c2 <= 'z');
}
}
알게 된 것
- 다른 사람들을 보면은 정규표현식을 활용하거나 하는데, 위처럼 character 의 값을 비교하면은 쉽게 알파벳을 거를 수 있다.
- 합집합과 교집합은 Map 의 비교를 통해 갯수를 구하거나 할 수 있다
- 중복이 허용된다면 카운터를 이용해야 한다
피드백
java stream 기능을 활용하면 보다 가독성 좋게 합집합, 교집합, 집합을 구해낼 수 있다.
private Map<String, Long> group(String word) {
return IntStream.range(0, word.length() - 1)
.mapToObj(index -> word.substring(index, index + 2))
.filter(text -> text.chars().allMatch(character -> Character.isAlphabetic((char) character)))
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
}
private Integer getIntersection(Map<String, Long> words1, Map<String, Long> words2) {
return words1.entrySet().stream()
.filter(entry -> words2.containsKey(entry.getKey()))
.map(entry -> Math.min(entry.getValue(), words2.get(entry.getKey())))
.mapToInt(Long::intValue)
.sum();
}
private Integer getUnion(Map<String, Long> words1, Map<String, Long> words2) {
Map<String, Long> copiedWords = new HashMap<>(words2);
words1.forEach((key, value) -> copiedWords.put(key, Math.max(value, words2.getOrDefault(key, 0L))));
return copiedWords.values().stream()
.mapToInt(Long::intValue)
.sum();
}
'프로그래밍 > programmers&bj' 카테고리의 다른 글
[JAVA] 다단계 칫솔 판매 (0) | 2022.03.28 |
---|---|
[python] k진수에서 소수 개수 구하기 (0) | 2022.03.22 |
[python] 메뉴 리뉴얼 (0) | 2022.03.13 |
[JAVA] 카카오프렌즈 컬러링북 (0) | 2022.03.06 |
[JAVA] 문자열 압축 (0) | 2022.02.21 |