section4의 문제를 순차적으로 풀어왔다면, 이 문제를 보았을 때
HashMap + TwoPointers + SlidingWindow를 사용하여
4.3 문제와 유사한 방법으로
아나그램 개수를 찾으면 된다는 것을 바로 파악할 수 있을 것이다.
일단 코드 먼저 ...
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Main {
public static boolean isAnagram(Map<Character, Integer> map1, Map<Character, Integer> map2){
/**
* 1. 일단 사용된 문자의 종류가 같아야 함
* 2. 그리고 동시에 -> 각 종류별 문자의 사용 빈도수가 같아야 함
* */
if(map1.keySet().equals(map2.keySet())){
for (Character key : map1.keySet()) {
if(map1.get(key) != map2.get(key)){
return false;
}
}
} else{
return false;
}
return true;
}
public static int solution(char[] charArr, char[] part, Map<Character, Integer> mapOfPart){
Map<Character, Integer> map = new HashMap<>();
int cnt = 0;
for(int i=0; i<part.length; i++){
Integer frequency = map.getOrDefault(charArr[i], 0);
map.put(charArr[i], frequency+1);
}
if(isAnagram(map, mapOfPart)){
cnt++;
}
int lt = 0;
int rt = part.length-1;
while(rt < charArr.length-1){
/** 여기서 빈도수가 0이면 아예 remove를 해줘야 -> isAnagram() 함수에서 -> 사용된 문자 종류의 개수가 같은걸로 판단된다. */
if(map.get(charArr[lt])==1){
map.remove(charArr[lt]);
} else{
map.put(charArr[lt], map.get(charArr[lt]) - 1);
}
lt++;
rt++;
Integer frequency = map.getOrDefault(charArr[rt], 0);
map.put(charArr[rt], frequency+1);
if(isAnagram(map, mapOfPart)){
cnt++;
}
}
return cnt;
}
public static void main(String[] args){
//0. Scanner 준비
Scanner sc = new Scanner(System.in);
//1. 입력
char[] charArr = sc.nextLine().toCharArray();
char[] part = sc.nextLine().toCharArray();
//2. part에 대한 빈도수를 partOfMap 에 기록
Map<Character, Integer> partOfMap = new HashMap<>();
for(int i=0; i<part.length; i++){
Integer frequency = partOfMap.getOrDefault(part[i], 0);
partOfMap.put(part[i], frequency+1);
}
//3. solution() 호출하여 결과 리턴
int cnt = solution(charArr, part, partOfMap);
//3. 결과 출력
System.out.println(cnt);
}
}
그런데 HashMap의 equals() 메소드는 , 이미 모든 (Key,Value) 의 쌍이 정확히 일치할 때 만 true를 리턴하도록 오버라이딩 되어 있다.
따라서 사용된 각 문자의 빈도수를 count할 때,
빈도수가 0이라면 (Key,Value)의 쌍을 아예 remove() 시키는 방식으로 count해나간다면
별도의 isAnagram() 같은 메소드 필요 없이,
HashMap의 equals() 메소드 자체만으로 아나그램 여부를 판별할 수 있다.
그렇게 isAnagram() 말고 , HashMap의 equals() 메소드를 사용하여 해결한 코드는 아래와 같다.
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Main {
public static boolean isAnagram(Map<Character, Integer> map1, Map<Character, Integer> map2){
/**
* 1. 일단 사용된 문자의 종류가 같아야 함
* 2. 그리고 동시에 -> 각 종류별 문자의 사용 빈도수가 같아야 함
* */
if(map1.keySet().equals(map2.keySet())){
for (Character key : map1.keySet()) {
if(map1.get(key) != map2.get(key)){
return false;
}
}
} else{
return false;
}
return true;
}
public static int solution(char[] charArr, char[] part, Map<Character, Integer> mapOfPart){
Map<Character, Integer> map = new HashMap<>();
int cnt = 0;
for(int i=0; i<part.length; i++){
Integer frequency = map.getOrDefault(charArr[i], 0);
map.put(charArr[i], frequency+1);
}
if(map.equals(mapOfPart)){
cnt++;
}
int lt = 0;
int rt = part.length-1;
while(rt < charArr.length-1){
/** 여기서 빈도수가 0이면 아예 remove를 해줘야 -> isAnagram() 함수에서 -> 사용된 문자 종류의 개수가 같은걸로 판단된다. */
if(map.get(charArr[lt])==1){
map.remove(charArr[lt]);
} else{
map.put(charArr[lt], map.get(charArr[lt]) - 1);
}
lt++;
rt++;
Integer frequency = map.getOrDefault(charArr[rt], 0);
map.put(charArr[rt], frequency+1);
if(map.equals(mapOfPart)){
cnt++;
}
}
return cnt;
}
public static void main(String[] args){
//0. Scanner 준비
Scanner sc = new Scanner(System.in);
//1. 입력
char[] charArr = sc.nextLine().toCharArray();
char[] part = sc.nextLine().toCharArray();
//2. part에 대한 빈도수를 partOfMap 에 기록
Map<Character, Integer> partOfMap = new HashMap<>();
for(int i=0; i<part.length; i++){
Integer frequency = partOfMap.getOrDefault(part[i], 0);
partOfMap.put(part[i], frequency+1);
}
//3. solution() 호출하여 결과 리턴
int cnt = solution(charArr, part, partOfMap);
//3. 결과 출력
System.out.println(cnt);
}
}