3. POSTECH Computer Algorithm Team
- String이란? 문자들의 나열로 이루어진 Object
ex) abcd, 1213121, AaBbCc, ....
- 모든 String은 유한개의 문자만을 사용한다.
ex) 소문자 26개, 0~9까지 10개, 대소문자 합쳐 52개 등등
문자열(string)
Introduction
4. POSTECH Computer Algorithm Team
Introduction
- 유한개의 문자만 사용하기 때문에, string과 number는 완벽히 1대1 대응이 된다.
- 현재 우리가 사용하는 수 체계는 10진수 체계다. 이 뜻은, 모든 number는 0~9로 되어있는 string에 1대1 대응하
여 표현하고 있다는 뜻이다.
ex) abc -> 1x26^2 + 2x26^1 + 3x26^0 = 731
5. POSTECH Computer Algorithm Team
Introduction
- String이 Number와 대응되기 때문에, Number의 성질, 연산을 그대로 사용 가능하다.
ex) 덧셈, 뺄셈, 곱셈, 나눗셈, XOR, 비교 등등
- Lexicographical Order : String의 사전식 비교
두 문자열을 왼쪽부터 순서대로 읽으며, 가장 먼저 작은 문자가 나오는 쪽이 더 작은 문자열이다.
ex) abcd < def , abcd < abea, abc < abcd
- Lexicographical Order는 Number의 Order와 완전히 다르다
ex) 1123 < 123 in Lexicographical Order
- Leading 0를 붙히면 Number의 Order와 같게 된다.
ex) 0123 < 1123 in Lexicographical Order
6. POSTECH Computer Algorithm Team
Introduction
Fastest Sort Algorithm
- 문자열의 길이가 L이라면, 비교 시간은 O(L)이다.
- N개의 문자열을 정렬한다고 가정하면, 시간은 O(NLlogN)
Q) 더 빠르게 정렬할 수 있는 방법은 없을까?
hint) 분할정복
7. POSTECH Computer Algorithm Team
- Matching : 두 String이 같으면 Matching이라고 한다.
- String Matching Problem : String A와 B가 주어진다. B가 A의 Substring인가?
ex1) bca는 abcabc의 Substring이다.
ex2) bab는 abcabc의 Substring이 아니다.
Q) 어떻게 알 수 있을까?
String Matching
String Matching
8. POSTECH Computer Algorithm Team
String Matching
A1) Naïve한 방법
- 하나하나 Matching해 본다!
- A에서 B와 길이가 같은 Substring을 전부 뽑아내고, B와 Matching 시킨다.
ex) abcabc의 길이 3짜리 Substring은 abc, bca, cab, abc가 있다. 이 중에 bca와 같은 String이 존재한다.
- A의 길이가 M, B의 길이가 N이라면, 시간 O(MN)
- 더 빠르게 할 수는 없을까?
9. POSTECH Computer Algorithm Team
String Matching
- 쓸데없는 비교가 너무 많다.
- A[a,a+1,...,a+b-1]과 B[1,2,...,b]가 Matching 되었다고 하자.
- A[a+b]와 B[b+1]이 달라, 처음부터 Matching을 한다고 하면, A[a+1]과 B[1]을 비교하게 된다.
- 하지만 이전 비교에서 A[a+1]은 B[2]와 같다는 것을 알 수 있다.
- B[2]와 B[1]이 다르다는 것만 안다면, A[a+1]과 B[1]을 비교하는 행동은 안하는게 맞다.
Q) 만약 Matching 하다가 실패했다고 하자. 그러면, 어디부터 다시 시작해야 할까?
10. POSTECH Computer Algorithm Team
String Matching
- Prefix Array : 공집합을 포함하여, string의 왼쪽부터 읽어서 나온 substring들의 모음
ex) B[] , B[1] , B[1,2] , B[1,2,3] , ..... B[1,2,...,M]
- A[a,...,a+b-1] 과 B[1,2,...,b]까지 Matching 되고 실패했다
= A[a,...,a+b-1] 과 B[1,2,...,b]는 같은 String이다.
- B[1,2,...,b]까지 Matching되고 실패했으면, 어디부터 다시 시작해야 하는가?
- B[1,2,...,n] = B[b-n,b-n+1,...,b]가 되는 n을 찾으면 된다!
- Prefix Array에서 n을 찾는 것을 Failure Function이라고 한다.
- Failure Function F : F(B[1,2,...,b]) = B[1,2,...,n]
11. POSTECH Computer Algorithm Team
String Matching
Failure Function은 수학적 귀납법으로 만들 수 있다.
- F(B[1]) = B[]
- B[1] , B[1,2] , ... , B[1,2,...,b]가 전부 만들어졌다 하자.
- F(B[1,2,...,b]) = B[1,2,...,n]이라 하자.
- B[n+1]과 B[b+1]이 같다면? F(B[1,2,...,b+1]) = B[1,2,...,n+1]
- 아니라면? F(B[1,2,...,n]) = B[1,2,...,m]이라 하자.
- B[m+1]과 B[b+1]이 같다면? F(B[1,2,...,b+1]) = B[1,2,...,m+1]
- 계속 아니라면? F(B[1,2,...,b+1]) = B[]
12. POSTECH Computer Algorithm Team
String Matching
그러면 B가 A의 Substring이란 것을 어떻게 알 수 있을까?
- A[a,a+1,...,a+b-1]과 B[1,2,...,b]가 matching 되었고, F(B[1,2,...,b]) = B[1,2,...,n]이라고 하자.
- Failure Function의 성질에 의해, A[a+b-n,a+b-n+1,...,a+b-1]과 B[1,2,...,n]은 이미 matching 되었다.
- 따라서 A[a+b]와 B[n+1]이 맞는지 확인하면 된다.
- 아니라면? B[1,2,...,n]의 Failure Function을 다시 확인한다.
- 시간 복잡도 : O(N + M)
- 이 Algorithm을 KMP Algorithm이라고 한다.
13. POSTECH Computer Algorithm Team
String Matching
예제 : abcac의 Failure Function을 만들고, abcabcd의 substring인지 확인 하시오.
15. POSTECH Computer Algorithm Team
String Matching
- KMP에서 했던 중요한 중요한 Idea를 떠올려보자.
- String B의 Prefix Array의 Failure Function을 만들었다.
- L개의 string들에 대해서도 Prefix Array를 만들면 어떨까?
16. POSTECH Computer Algorithm Team
- Trie : L개의 String들의 Prefix Array로 되어있는 Graph
- Trie의 각 Node들은 String들의 Prefix를 의미한다.
ex) 공집합, B[0][0], B[0][0,1], B[0][0,1,2], ...
- Trie의 각 Edge들은 Directed Edge이다.
- A->B라는 의미는, string A의 끝에 문자 1개만 붙이면 string B가 된다는 의미다.
ex) B[0][0] -> B[0][0,1] -> B[0][0,1,2] -> ...
Trie
Trie
18. POSTECH Computer Algorithm Team
Trie
- Trie는 DAG구조를 이루고 있다.
- A에서 B로 가는 path가 있다고 하자. 그러면, B의 길이는 A의 길이보다 길다.
- 이때, B->A라면, A는 B보다 길이가 기므로, A는 A보다 길이가 길게 된다.(모순)
- 따라서, Trie에는 cycle이 존재하지 않으며, DAG다.
19. POSTECH Computer Algorithm Team
Trie
- Trie에는 Hidden Edge와 Terminal Node가 존재한다.
- Hidden Edge: Failure Function을 의미한다.
- Hidden Edge A->B란 의미는, F(A) = B를 의미한다.
- Terminal Node란, String Matching을 하다가 Terminal Node에 도달한다면, 바로 종료하는 Node다.
- Terminal Node는 B[0], B[1],...,B[L-1]을 substring으로 가지는 Node다.
20. POSTECH Computer Algorithm Team
Trie
- abc, abcde로 되어있는 Trie를 생각하자.
- String Matching 도중 abc, abcde node에 도착하면, substring을 찾은 것이기 때문에 종료해야 한다.
- 하지만 abcd 역시 종료조건이다. 왜냐하면 abc를 내포하고 있기 때문이다.
21. POSTECH Computer Algorithm Team
Trie
- Failure Function은 KMP때와 똑같이 만들면 된다.
- F(B[0,1,...,l])을 구하고 싶다. F(B[0,1,...,l-1]) = C[0,1,...,n]이라고 하자.
- C[0,1,...,n]의 Edge중 B[l]이라 이름이 붙은 Edge가 있는가?
있으면 F(B[0,1,...,l]) = C[0,1,...,n]의 Edge가 가리키는 node.
- 만약 Failure Function이 Terminal Node면, 이 Node도 Terminal Node다.
23. POSTECH Computer Algorithm Team
Trie
- 확장된 String Matching Problem으로 돌아오자. 어떻게 풀 수 있을까?
- L개의 String에 대한 Trie를 만든 뒤, KMP에서 했던 것처럼 Trie 위에서 String을 읽어가면 된다.
- 만약 Trie의 Terminal Node에 도달했다면, 답은 True
- 모든 String을 읽고 도달하지 못했다면, 답은 False
- 시간복잡도 : O(N+LM)
- 이 Algorithm을 Aho-Corasick 알고리즘이라고 한다.
24. POSTECH Computer Algorithm Team
- 앞서 말했듯, String과 Number는 1대1 대응이 된다.
- 길이 L인 string이라면, 대응되는 number는 26^L 이하의 숫자들이 된다.
- 이는 컴퓨터의 물리적 공간으로 절대 불가능하다.
- 따라서, 컴퓨터로 표현할 수 있는 M개의 숫자들로 string을 대응시키는 방법을 Hashing이라고 한다.
- 원래 26^L개의 숫자가 필요한데, M개만 사용하므로, 당연하게도 서로 다른 두 string이 같은 값을 나타낼 수도
있다. 이러한 현상을 충돌이라고 한다.
- 충돌은 Hashing에서 필수불가결하게 일어나며, 이 충돌을 줄이는 것이 매우 중요하다.
Hashing
Hashing
25. POSTECH Computer Algorithm Team
Hashing
- 아주 간단하게 생각해서, N개의 String을 Hashing할 때, M개의 공간에 아주 골고루 들어간다면 어떻게 될까?
- String의 충돌 횟수는 약 N/M일 것이다.
- 여기서 M을 아주 크게 늘린다면, 충돌 횟수는 매우 작아질 것이다.
- 따라서, M을 아주 크게 늘리면 된다. 최대 가능한 구간은, long long int(64bit)가 될 것이다.
Q) M개의 공간에 골고루 들어가게 Hashing하는 방법은 무엇일까?
26. POSTECH Computer Algorithm Team
Hashing
- String을 26진법 대신 P진법으로 나타내면 된다.
- 당연히 overflow가 일어나지만, 무시해도 된다.
- 충돌이 일어나는 이상, number에서 다시 string으로 복구하지 못하기 때문이다.
- 그리고 같은 string을 hashing한다면, overflow가 일어나는 지점도 같기 때문에 overflow와 상관없이
Number는 같을 것이다.
- P는 아주 큰 소수를 잡으면 좋다. 저 같은 경우는 99999971을 사용합니다.
ex) abc => a*P^2 + b*P^1 + C
27. POSTECH Computer Algorithm Team
Hashing
Q) 길이 L짜리 string이 있다. 이 string의 substring중에, 가장 긴 Palindrome을 찾고 싶다.
- 이 문제는 DP로 O(L)만에 해결이 가능하다. 하지만 매우 어렵고 복잡하다.
- Hashing을 이용하면 우리가 아는 범위 내에서, O(LlogL) 안에 해결이 가능하다.
- 자세한 것은 문제로 남긴다.
28. POSTECH Computer Algorithm Team
https://www.acmicpc.net/problem/1786 (필수)
https://www.acmicpc.net/problem/13275 (필수)
https://www.acmicpc.net/problem/9248 (필수)
https://www.acmicpc.net/problem/9250 (필수)
https://www.acmicpc.net/problem/9249
https://www.acmicpc.net/problem/9253
오늘의 문제