1. ๋ฌธ์ ์ค๋ช
2. ์ ๊ทผ ๋ฐฉ์
(1) HashSet
์ ๋์ค๋ ๋ชจ๋ ๋ถ๋ถ ๋ฌธ์์ด์ ์ ์ฅํ๋ค.
(2) map1
, map2
๋ HashMap์ผ๋ก์ ๊ฐ ๋ฌธ์์ด์ ๋ฌธ์๊ฐ key, ๊ทธ ๋ฌธ์๊ฐ ๋์ค๋ ๊ฐ์๊ฐ value์ด๋ค.
(3) hashSet์ ์ ์ฅ๋์ด ์๋ ๋ฌธ์๋ฅผ ํ๋์ฉ ๊บผ๋ธ๋ค. ํด๋น ๋ฌธ์์ ๊ฐ์๋ฅผ map1๊ณผ map2์์ ๊บผ๋ด์, ํฉ์งํฉ๊ณผ ๊ต์งํฉ์ ๊ณ์ฐํ๋ค.ํฉ์งํฉ
: ๋ ์ค ๋ ๊ฐ์๊ฐ ๋ง์ ์ชฝ์ ๊ฐ์๋ฅผ ๋ํ๋ค.๊ต์งํฉ
: ๋ ์ค ํ๋๋ผ๋ ๊ฐ์ด ์กด์ฌํ์ง ์์ผ๋ฉด ๋์ด๊ฐ๋ค. ๋ ๋ค ํด๋น ๊ฐ์ ๊ฐ์ง๊ณ ์๋ค๋ฉด ๊ฐ์๊ฐ ๋ ์ ์ ์ชฝ์ ๊ฐ์๋ฅผ ๋ํ๋ค.
3. ์ฝ๋ ๋ถ์
import java.io.*;
import java.util.*;
class Solution {
public int solution(String str1, String str2) {
HashSet<String> set = new HashSet<>();
HashMap<String, Integer> map1 = new HashMap<>();
HashMap<String, Integer> map2 = new HashMap<>();
split_str(str1, map1, set); split_str(str2, map2, set);
// 2. ๊ต์งํฉ, ํฉ์งํฉ ๊ตฌํ๊ธฐ
double union = 0;
double inter = 0;
for(String temp : set){
int cnt1 = map1.get(temp) == null ? 0 : map1.get(temp);
int cnt2 = map2.get(temp) == null ? 0 : map2.get(temp);
union += Math.max(cnt1, cnt2);
if(cnt1 == 0 || cnt2 == 0) continue;
else{
inter += Math.min(cnt1,cnt2);
}
}
if(map1.size() == 0 && map2.size() == 0) return 65536;
return (int)((inter/union)*65536) ;
}
// 1. ๊ธ์ ์๋ผ์ map์ ๋ฃ๊ธฐ
public void split_str(String str, HashMap<String,Integer> map, HashSet<String> set) {
for(int i = 2; i <= str.length(); i+=1){
boolean isValid = true;
String now = str.substring(i-2, i);
// 97, 122, 65, 90
for(int j = 0; j<2; j++){
if((now.charAt(j)>= 97 && now.charAt(j)<= 122)||
(now.charAt(j)>= 65 && now.charAt(j)<= 90)) continue;
isValid = false;
}
if(isValid) {
set.add(now.toLowerCase());
map.compute(now.toLowerCase(),(key,oldValue) -> oldValue== null? 1 : oldValue+1);
}
}
}
}
4. ์ฑ์ฅ ํ๊ธฐ
๋ค๋ฅธ ์ฌ๋์ ํ์ด๋ก ๊ณต๋ถํด๋ณด๊ฒ ๋ค.
class Solution {
// Character.MAX_VALUE๋ 65535๋ก, ์ฌ๊ธฐ์ 1์ ๋ํ 65536์ MULTIPLIER๋ก ์ค์
private static final Integer MULTIPLIER = Character.MAX_VALUE + 1;
public int solution(String str1, String str2) {
// ๋ ์
๋ ฅ ๋ฌธ์์ด์ ์๋ฌธ์๋ก ๋ณํ
String word1 = str1.toLowerCase();
String word2 = str2.toLowerCase();
// ๊ฐ ๋ฌธ์์ด์ ๋ถ๋ถ์งํฉ์ผ๋ก ๊ทธ๋ฃนํํ์ฌ Map์ผ๋ก ๋ฐํ
Map<String, Long> words1 = group(word1);
Map<String, Long> words2 = group(word2);
// ๋ ๋ฌธ์์ด์ ๊ต์งํฉ ํฌ๊ธฐ๋ฅผ ๊ณ์ฐ
Integer intersection = getIntersection(words1, words2);
// ๋ ๋ฌธ์์ด์ ํฉ์งํฉ ํฌ๊ธฐ๋ฅผ ๊ณ์ฐ
Integer union = getUnion(words1, words2);
// ๊ต์งํฉ๊ณผ ํฉ์งํฉ์ด ๋ชจ๋ 0์ธ ๊ฒฝ์ฐ, MULTIPLIER ๋ฐํ (๋ ๋ฌธ์์ด์ด ๋ชจ๋ ๋น์ด์์ ๊ฒฝ์ฐ)
if (intersection.equals(union) && union.equals(0)) {
return MULTIPLIER;
}
// ๊ต์งํฉ ํฌ๊ธฐ๋ฅผ ํฉ์งํฉ ํฌ๊ธฐ๋ก ๋๋๊ณ , MULTIPLIER๋ฅผ ๊ณฑํ์ฌ ๊ฒฐ๊ณผ ๋ฐํ
return (int) (intersection.doubleValue() / union.doubleValue() * MULTIPLIER);
}
// ์ฃผ์ด์ง ๋ฌธ์์ด์์ 2๊ธ์์ฉ ๋์ด ๋ถ๋ถ์งํฉ์ ๋ง๋ค๊ณ , ๊ฐ ๋ถ๋ถ์งํฉ์ ๋น๋์๋ฅผ ๊ณ์ฐํ๋ ํจ์
private Map<String, Long> group(String word) {
// ๋ฌธ์์ด์ ๊ธธ์ด์์ 1์ ๋บ ๋ฒ์์์ ๋ฐ๋ณต (๋ง์ง๋ง 2๊ธ์๊น์ง ํฌํจํ๊ธฐ ์ํด)
return IntStream.range(0, word.length() - 1)
// ๊ฐ ์ธ๋ฑ์ค์์ 2๊ธ์์ฉ ๋ถ๋ถ ๋ฌธ์์ด ์์ฑ
.mapToObj(index -> word.substring(index, index + 2))
// ์์ฑ๋ 2๊ธ์ ๋ถ๋ถ ๋ฌธ์์ด์ด ๋ชจ๋ ์ํ๋ฒณ์ธ์ง ํ์ธ
.filter(text -> text.chars().allMatch(character -> Character.isAlphabetic((char) character)))
// ์ํ๋ฒณ ๋ถ๋ถ ๋ฌธ์์ด์ Map์ผ๋ก ๊ทธ๋ฃนํ, ๊ฐ ๋ฌธ์์ด์ ๋น๋๋ฅผ ๊ณ์ฐํ์ฌ Map์ผ๋ก ๋ฐํ
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
}
// ๋ Map์์ ๊ณตํต์ผ๋ก ์กด์ฌํ๋ 2๊ธ์ ๋ถ๋ถ ๋ฌธ์์ด์ ์ต์ ๋น๋๋ฅผ ํฉ์ฐํ์ฌ ๊ต์งํฉ ํฌ๊ธฐ๋ฅผ ๊ณ์ฐํ๋ ํจ์
private Integer getIntersection(Map<String, Long> words1, Map<String, Long> words2) {
return words1.entrySet().stream()
// words2์๋ ์กด์ฌํ๋ ํค๋ง ํํฐ๋ง
.filter(entry -> words2.containsKey(entry.getKey()))
// ๋ Map์์ ๊ณตํต ํค์ ๋น๋ ์ค ์ต์๊ฐ์ ๊ฐ์ ธ์ด
.map(entry -> Math.min(entry.getValue(), words2.get(entry.getKey())))
// ์ด ์ต์๊ฐ๋ค์ ํฉ์ฐํ์ฌ ๊ต์งํฉ ํฌ๊ธฐ๋ฅผ ๊ณ์ฐ
.mapToInt(Long::intValue)
.sum();
}
// ๋ Map์์ ๋ชจ๋ 2๊ธ์ ๋ถ๋ถ ๋ฌธ์์ด์ ์ต๋ ๋น๋๋ฅผ ํฉ์ฐํ์ฌ ํฉ์งํฉ ํฌ๊ธฐ๋ฅผ ๊ณ์ฐํ๋ ํจ์
private Integer getUnion(Map<String, Long> words1, Map<String, Long> words2) {
// words2์ ๋ณต์ฌ๋ณธ์ ์์ฑํ์ฌ, words1์ ๊ฐ์ ๋ณํฉ
Map<String, Long> copiedWords = new HashMap<>(words2);
// words1์ ๊ฐ ์ํธ๋ฆฌ์ ๋ํด, words2์์ ์ต๋ ๋น๋์๋ฅผ ์ ์ฅ
words1.forEach((key, value) -> copiedWords.put(key, Math.max(value, words2.getOrDefault(key, 0L))));
// ๋ชจ๋ ๊ฐ์ ํฉ์ฐํ์ฌ ํฉ์งํฉ ํฌ๊ธฐ๋ฅผ ๊ณ์ฐ
return copiedWords.values().stream()
.mapToInt(Long::intValue)
.sum();
}
}
โ๏ธDriling
(1)
.filter(text -> text.chars().allMatch(character -> Character.isAlphabetic((char) character)))
์ฉ์ด | ์ค๋ช |
---|---|
text.chars() |
์ฌ๊ธฐ์ text ๋ ๋ฌธ์์ด์ด๋ค. ์ด ๋ฌธ์์ด์ IntStream() ์ผ๋ก ๋ณํํ๋ค.๋ฐ๋ผ์ ๋ค์ Stream์์๋ text์ ๋ฌธ์ ํ๋ํ๋๊ฐ intํํ๋ก chaining์ ์ ๋ ฅ ๋๋ค. |
.allMatch(n -> predicate(n)) |
Stream์ ์ฃผ์ด์ง ๋ชจ๋ ์์๊ฐ predicate(n)๋ฅผ ๋ง์กฑํ๋ค๋ฉด true ์๋๋ฉด false ๋ฐํํ๋ค. |
Character.isAlphabetic(n) |
n์ด ์ํ๋ฒณ์ ํด๋นํ๋ฉด true, ์๋๋ฉด false ๋ฐํ |
(2)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
์ฉ์ด | ์ค๋ช |
---|---|
Collectors.groupingBy(A,B) |
Stream์ ์์๋ค์ ์ฒซ ๋ฒ์งธ ์ธ์๋ฅผ ๊ธฐ์ค์ผ๋ก ๊ทธ๋ฃนํ ํ๋ค. |
Function.identity() |
Stream์์ ์ฃผ์ด์ง ์
๋ ฅ์ ๊ทธ๋๋ก ๋ฐํํ๋ ํจ์ ์๋ฅผ ๋ค์ด, "ab", "ab", "cd"๋ผ๋ ๋ฌธ์์ด๋ค์ด ์๋ค๋ฉด, "ab"๋ ๋ ๋ฒ, "cd"๋ ํ ๋ฒ ๊ทธ๋ฃนํ ๋๋ค. |
Collectors.counting() |
์ฒซ ๋ฒ์งธ ์ธ์๋ก ๊ทธ๋ฃนํ ํ์์ ๋, ํด๋น ๊ทธ๋ฃน์ ๋น๋์๋ฅผ ์ธ์ด์, Map<String, Long> ํํ๋ก ๋ฐํํ๋ค."ab"๋ผ๋ ๋ฌธ์์ด์ด ๋ ๋ฒ ๋ฑ์ฅํ์ผ๋ฉด, counting() ์ 2๋ฅผ ๋ฐํ |
0