[JAVA/SWEA] 3135: 홍준이의 사전놀이

👀 문제

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV_6pTXqsXUDFAWS&categoryId=AV_6pTXqsXUDFAWS&categoryType=CODE

👊 도전

1. 설계

  1. 트라이를 이용한다.

2. 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import java.util.*;
/**
 *
 * @author HEESOO
 *
 */
 public class UserSolution {
    static Trie[] tries;
    public void init() {
        tries=new Trie[26];
    }
    
    public void insert(int buffer_size, String buf) {
        int root=buf.charAt(0)-'a';
        if(tries[root]==null) tries[root]=new Trie();
        tries[root].insert(buf);
    }
    
    public int query(int buffer_size, String buf) {
        int root=buf.charAt(0)-'a';
        if(tries[root]==null) return 0;
        return tries[root].getCnt(buf);
    }
}

class Trie{
    Node root;
    public Trie() {
        this.root=new Node();
    }
    public void insert(String word) {
        Node node=root;
        for(int i=0;i<word.length();i++) {
            node=node.children.computeIfAbsent(word.charAt(i), c->new Node());
            node.cnt++;
        }
    }
    
    public int getCnt(String query) {
        Node node=root;
        for(int i=0;i<query.length();i++) {
            if(!node.children.containsKey(query.charAt(i))) return 0;
            node=node.children.get(query.charAt(i)); 
        }
        return node.cnt;
    }
}

class Node{
    HashMap<Character, Node> children;
    int cnt;
    public Node() {
        this.children=new HashMap<>();
        this.cnt=0;
    }
}

3. 결과

실행결과 🤟 성공 🤟

4. 설명

  1. Usersolution
    • init(): Trie[] 배열을 초기화한다. 인덱스 0번부터 a로 쓸 것이므로 배열 사이즈를 26으로 초기화했다.
    • insert(): 문자열 buf의 시작 알파벳 아스키코드를 root에 저장한다. 배열 trie에 해당 알파벳으로 시작한 단어가 없다면, 트라이 객체를 하나 선언한 후, Trie클래스의 insert()를 호출한다.
    • query(): buf의 시작 알파벳을 찾아 root에 저장한다. 해당 배열이 null이라면 root로 시작하는 단어가 없어서 객체 선언이 안된것이므로 0을 리턴한다. 아닐 경우, getCnt()로 개수를 받아 리턴한다.
  2. Trie
    • Trie(): 생성자이다. 시작 노드(root)를 만든다.
    • insert(): node는 트라이 내에서 현재 내 위치이다. word의 문자를 하나씩 체크해 트라이에 저장한다. 현재 node의 자식들(해시맵)에 word.charAt(i)가 있는지 확인한다. 없다면 하나 생성 후, 거기로 내려간다. 현재 삽입한(또는 기존에 존재하는) node까지 단어가 일치하는 것이므로 node.cnt++한다.
    • getCnt(): node로 트리를 이동한다. query의 문자를 하나씩 체크하며, 현재 위치 node의 자식 노드들 중 i값이 없다면 query 단어가 없는 것이므로 0을 리턴한다. for문을 종료해야 그곳 node.cnt를 리턴한다.
  3. Node
    • children은 node의 자식 노드들을 해시맵으로 저장한다. 중복을 거르고 빠르게 찾을 수 있도록 해시맵을 사용한다.
    • cnt는 현재 node까지 일치하는 단어의 개수이다.

👏 해결 완료!

참고