TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
z_function.cpp
Go to the documentation of this file.
1
14#include <cstdint>
15#include <iostream>
16#ifdef _MSC_VER
17#include <string>
18#else
19#include <cstring>
20#endif
21#include <cassert>
22#include <vector>
23
29std::vector<uint64_t> Z_function(const std::string &pattern) {
30 uint64_t pattern_length = pattern.size();
31 std::vector<uint64_t> z(pattern_length, 0);
32
33 for (uint64_t i = 1, l = 0, r = 0; i < pattern_length; i++) {
34 if (i <= r) {
35 z[i] = std::min(r - i + 1, z[i - l]);
36 }
37 while (i + z[i] < pattern_length &&
38 pattern[z[i]] == pattern[i + z[i]]) {
39 z[i]++;
40 }
41 if (i + z[i] - 1 > r) {
42 r = i + z[i] - 1;
43 }
44 }
45 return z;
46}
47
54std::vector<uint64_t> find_pat_in_text(const std::string &pattern,
55 const std::string &text) {
56 uint64_t text_length = text.size(), pattern_length = pattern.size();
57 std::vector<uint64_t> z = Z_function(pattern + '#' + text);
58 std::vector<uint64_t> matching_indexes;
59
60 for (uint64_t i = 0; i < text_length; i++) {
61 if (z[i + pattern_length + 1] == pattern_length) {
62 matching_indexes.push_back(i);
63 }
64 }
65 return matching_indexes;
66}
67
72static void test() {
73 // usual case
74 std::string text1 = "alskfjaldsabc1abc1abcbksbcdnsdabcabc";
75 std::string pattern1 = "abc";
76
77 // matching_indexes1 gets the indexes where pattern1 exists in text1
78 std::vector<uint64_t> matching_indexes1 = find_pat_in_text(pattern1, text1);
79 assert((matching_indexes1 == std::vector<uint64_t>{10, 14, 18, 30, 33}));
80
81 // corner case
82 std::string text2 = "greengrass";
83 std::string pattern2 = "abc";
84
85 // matching_indexes2 gets the indexes where pattern2 exists in text2
86 std::vector<uint64_t> matching_indexes2 = find_pat_in_text(pattern2, text2);
87 assert((matching_indexes2 == std::vector<uint64_t>{}));
88
89 // corner case - empty text
90 std::string text3 = "";
91 std::string pattern3 = "abc";
92
93 // matching_indexes3 gets the indexes where pattern3 exists in text3
94 std::vector<uint64_t> matching_indexes3 = find_pat_in_text(pattern3, text3);
95 assert((matching_indexes3 == std::vector<uint64_t>{}));
96
97 // corner case - empty pattern
98 std::string text4 = "redsand";
99 std::string pattern4 = "";
100
101 // matching_indexes4 gets the indexes where pattern4 exists in text4
102 std::vector<uint64_t> matching_indexes4 = find_pat_in_text(pattern4, text4);
103 assert((matching_indexes4 == std::vector<uint64_t>{0, 1, 2, 3, 4, 5, 6}));
104}
105
110int main() {
111 test(); // run self-test implementations
112 return 0;
113}
static void test()
Self-test implementations.
std::vector< uint64_t > Z_function(const std::string &pattern)
for IO operations
std::vector< uint64_t > find_pat_in_text(const std::string &pattern, const std::string &text)
Using Z_function to find a pattern in a text.
int main()
Main function.