Skip to content

Commit e82a22d

Browse files
committed
[String] baekjoon-14426
1 parent 5054c79 commit e82a22d

File tree

5 files changed

+144
-0
lines changed

5 files changed

+144
-0
lines changed

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@
242242
| # || Problem | Note |
243243
| :-: | :-: | :------------------------------------------------- | :----- |
244244
| 01 | | [Baekjoon-14425 문자열 집합](./src/String/P14425) | |
245+
| 02 | | [Baekjoon-14426 접두사 찾기](./src/String/P14426) | |
245246

246247
---
247248

Diff for: src/String/P14426/Main.java

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package String.P14426;
2+
3+
import java.io.*;
4+
import java.util.*;
5+
6+
public class Main {
7+
8+
static int N, M;
9+
10+
public static void main(String[] args) throws Exception {
11+
System.setIn(new FileInputStream("src/String/P14426/input.txt"));
12+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
13+
StringTokenizer st = new StringTokenizer(br.readLine());
14+
15+
N = Integer.parseInt(st.nextToken());
16+
M = Integer.parseInt(st.nextToken());
17+
18+
String[] S = new String[N];
19+
for (int i = 0; i < N; i++) S[i] = br.readLine();
20+
21+
int ans = 0;
22+
for (int i = 0; i < M; i++) {
23+
String s = br.readLine();
24+
for (int j = 0; j < N; j++) {
25+
if (S[j].startsWith(s)) {
26+
ans ++;
27+
break;
28+
}
29+
}
30+
}
31+
32+
System.out.println(ans);
33+
}
34+
}

Diff for: src/String/P14426/README.md

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
## [baekjoon-14426] 접두사 찾기
2+
3+
![image](https://user-images.githubusercontent.com/22045163/102746718-26d22000-43a2-11eb-806f-7b114b08f9b8.png)
4+
5+
### 시간 복잡도와 공간 복잡도 사이
6+
7+
이 문제를 단순하게 문자열 배열과 substring 개념을 사용하여 푼다면
8+
간단하여 풀이 속도가 빠르고, 문제에서 주어진 범위가 크지 않기 때문에 무난하게 풀 수 있을 것이다.
9+
하지만 알고리즘은 늘 더 좋은 효율성을 생각해야 하는 문제이기 때문에, 시간 복잡도를 줄일 방법을 생각해봤을 때
10+
**Trie**를 생각해낼 수 있었다. 특히 접두사를 찾는 문제이기 때문에 아주 적합하다.
11+
12+
두 가지 풀이법을 모두 구현하여 비교해보았다.
13+
14+
- [배열과 `startsWith` 메서드를 사용한 풀이](Main.java)
15+
- [Trie를 사용한 풀이](usingTrie.java)
16+
17+
![image](https://user-images.githubusercontent.com/22045163/102748579-c5ac4b80-43a5-11eb-945e-633c8d023638.png)
18+
19+
Trie를 사용했을 때 확실히 시간 복잡도가 줄어들지만, Trie는 공간 복잡도가 크다는 단점이 있다.
20+
두 가지 알고리즘을 모두 알고 상황에 따라 알맞게 적용할 수 있어야 할 것 같다.

Diff for: src/String/P14426/input.txt

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
5 10
2+
baekjoononlinejudge
3+
startlink
4+
codeplus
5+
sundaycoding
6+
codingsh
7+
baekjoon
8+
star
9+
start
10+
code
11+
sunday
12+
coding
13+
cod
14+
online
15+
judge
16+
plus
17+
18+
output 7
19+
baekjoon
20+
star
21+
start
22+
code
23+
sunday
24+
coding
25+
cod

Diff for: src/String/P14426/usingTrie.java

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package String.P14426;
2+
3+
import java.io.*;
4+
import java.util.*;
5+
6+
public class usingTrie {
7+
8+
static int N, M;
9+
10+
public static void main(String[] args) throws Exception {
11+
System.setIn(new FileInputStream("src/String/P14426/input.txt"));
12+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
13+
StringTokenizer st = new StringTokenizer(br.readLine());
14+
15+
N = Integer.parseInt(st.nextToken());
16+
M = Integer.parseInt(st.nextToken());
17+
18+
Trie t = new Trie();
19+
while (N-- > 0) t.insert(br.readLine());
20+
21+
int ans = 0;
22+
while (M-- > 0) {
23+
if (t.search(br.readLine())) ans ++;
24+
}
25+
26+
System.out.println(ans);
27+
}
28+
}
29+
30+
class Trie {
31+
TrieNode root = new TrieNode();
32+
33+
void insert(String word) {
34+
TrieNode current = root;
35+
for (int i = 0; i < word.length(); i++) {
36+
char c = word.charAt(i);
37+
if (!current.hasChild(c))
38+
current.children[c - 'a'] = new TrieNode();
39+
current = current.getChild(c);
40+
}
41+
}
42+
43+
boolean search(String word) {
44+
TrieNode current = root;
45+
for (int i = 0; i < word.length(); i++) {
46+
char c = word.charAt(i);
47+
if (current.hasChild(c)) current = current.getChild(c);
48+
else return false;
49+
}
50+
return true;
51+
}
52+
}
53+
54+
class TrieNode {
55+
TrieNode[] children = new TrieNode[26];
56+
57+
boolean hasChild(char c) {
58+
return children[c - 'a'] != null;
59+
}
60+
61+
TrieNode getChild(char c) {
62+
return children[c - 'a'];
63+
}
64+
}

0 commit comments

Comments
 (0)