문자열이 만약에 "dabcabkabcabd"라고 하자.
이 문자열 안에 "abcabd"라는 문자가 있는지 확인해보고자 한다.
만약 brute force로 검색한다면 복잡도는 O(N * M)이 될 것이다.
이것을 O(N + M)~~ O(N)으로 할 수가 있다.
사실 문자열 검색의 복잡도는 O(N)으로 끝내야 한다.
만약 두 문자열이 같다면 그 해쉬 값도 같다고 볼 수 있다.
슬라이딩 윈도우를 하면서, hash값만 비교하고(복잡도 O(N))
hash 값이 일치한다면 일치하는 hash값끼리만 문자열을 일일히 비교해보면 된다(복잡도 O(M))
코드 >>
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
|
#include <iostream>
#include <string>
// C++ Rabin-Kaap 알고리즘 쉽게 구현
int main()
{
std::string find = "abcabd"; // Hash 값 : 12449668180088197040
std::string b = "abcabd"; // Hash 값 : 12449668180088197040
std::string total = "dabcabkabcabd"; // Hash 값 : 7653540513724806762
std::hash<std::string> str_hash;
// 같은 string이면 hash value가 같다.
std::cout << "hash value of abcabd : " << str_hash(find) << std::endl;
std::cout << "hash value of abcabd : " << str_hash(b) << std::endl;
std::cout << "hash value of dabcabkabcabd : " << str_hash(total) << std::endl;
size_t Findsize = find.size();
size_t Totalsize = total.size();
;
for (size_t i = 0; i <= Totalsize - Findsize; i++)
{
std::string tempString = total.substr(i, Findsize);
// 해쉬값을 비교하므로 O(N) 가능
if ( str_hash(tempString) == str_hash(find))
{
// 해쉬 충돌이 일어날 수 있으므로 일일히 문자열을 비교해 본다.
// 그렇다면 시간 복잡도는 O(N+M) --> O(N)
if (tempString == find)
{
std::cout << "검색어를 찾았습니다. 정답은 : " << tempString << std::endl;
}
}
}
return 0;
}
|
'C' 카테고리의 다른 글
c++ leetcode 125 valid palindrome solution (0) | 2021.07.06 |
---|---|
c++ Rabin-Kaap 알고리즘을 활용한 leetcode 796번 Rotate String (O(N)) (0) | 2021.07.06 |
c++ O(N)으로 2D matrix 원소 찾기 (0) | 2021.07.04 |
c++ 배열 image in-place로 rotate 하기 (0) | 2021.07.04 |
c++ leetcode array find duplicate by O(N) (0) | 2021.07.04 |