1
1
/* *
2
2
* @file
3
- * @brief The [Z function](https://cp-algorithms.com/string/z-function.html) for finding occurences of a pattern
4
- * within a piece of text with time and space complexity O(n + m)
5
- * @details
3
+ * @brief The [Z function](https://cp-algorithms.com/string/z-function.html) for
4
+ * finding occurences of a pattern within a piece of text with time and space
5
+ * complexity O(n + m)
6
+ * @details
6
7
* DESCRIPTION
7
- * 1. The Z-function for a string is an array of length n where the
8
- * i-th element is equal to the greatest number of characters starting
8
+ * 1. The Z-function for a string is an array of length n where the
9
+ * i-th element is equal to the greatest number of characters starting
9
10
* from the position i that coincide with the first characters of s.
10
11
* 2. Eg string : ababb then z[2]=2 as s[2]=s[0] and s[3]=s[1] and s[4]!=s[2]
11
12
* @author [Ritika Gupta](https://github.com/RitikaGupta8734)
12
13
*/
13
14
14
- #include < iostream> // / for IO operations
15
+ #include < iostream> // / for IO operations
15
16
#ifdef _MSC_VER
16
17
#include < string> // / for string (use this for MS Visual C++)
17
18
#else
18
- #include < cstring> // / for string
19
+ #include < cstring> // / for string
19
20
#endif
20
- #include < vector > // / for std::vector
21
- #include < cassert > // / for assert
21
+ #include < cassert > // / for assert
22
+ #include < vector > // / for std::vector
22
23
23
24
/* *
24
25
* @brief Generate the Z-function for the inputted string.
27
28
*/
28
29
std::vector<int > Z_function (const std::string &pattern) {
29
30
int pattern_length = pattern.size ();
30
- std::vector<int > z (pattern_length,0 );
31
-
32
- for (int i = 1 ,l = 0 ,r = 0 ; i < pattern_length; i++) {
33
- if (i<=r)z[i]=std::min (r-i+1 ,z[i-l]);
34
- while (i+z[i]<pattern_length && pattern[z[i]]==pattern[i+z[i]]) z[i]++;
35
- if (i+z[i]-1 >r)r=i+z[i]-1 ;
31
+ std::vector<int > z (pattern_length, 0 );
32
+
33
+ for (int 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
+ while (i + z[i] < pattern_length && pattern[z[i]] == pattern[i + z[i]])
37
+ z[i]++;
38
+ if (i + z[i] - 1 > r)
39
+ r = i + z[i] - 1 ;
36
40
}
37
41
return z;
38
42
}
@@ -41,36 +45,38 @@ std::vector<int> Z_function(const std::string &pattern) {
41
45
* @brief Using Z_function to find a pattern in a text
42
46
* \param[in] pattern string pattern to search
43
47
* \param[in] text text in which to search
44
- * \returns a vector of starting indexes where pattern is found in the text
48
+ * \returns a vector of starting indexes where pattern is found in the text
45
49
*/
46
- std::vector<int > find_pat_in_text (const std::string &pattern, const std::string &text) {
50
+ std::vector<int > find_pat_in_text (const std::string &pattern,
51
+ const std::string &text) {
47
52
int text_length = text.size (), pattern_length = pattern.size ();
48
- std::vector<int > z = Z_function (pattern+ ' #' + text);
53
+ std::vector<int > z = Z_function (pattern + ' #' + text);
49
54
std::vector<int > matching_indexes;
50
55
51
56
for (int i = 0 ; i < text_length; i++) {
52
- if (z[i+pattern_length+1 ]==pattern_length) matching_indexes.push_back (i);
57
+ if (z[i + pattern_length + 1 ] == pattern_length)
58
+ matching_indexes.push_back (i);
53
59
}
54
60
return matching_indexes;
55
- }
61
+ }
56
62
57
63
/* *
58
64
* @brief Self-test implementations
59
65
* @returns void
60
66
*/
61
- static void test (){
67
+ static void test () {
62
68
// usual case
63
69
std::string text1 = " alskfjaldsabc1abc1abcbksbcdnsdabcabc" ;
64
70
std::string pattern1 = " abc" ;
65
-
66
- std::vector<int > matching_indexes1= find_pat_in_text (pattern1,text1);
67
- assert ((matching_indexes1 == std::vector<int >{10 ,14 ,18 ,30 ,33 }));
68
-
71
+
72
+ std::vector<int > matching_indexes1 = find_pat_in_text (pattern1, text1);
73
+ assert ((matching_indexes1 == std::vector<int >{10 , 14 , 18 , 30 , 33 }));
74
+
69
75
// corner case
70
76
std::string text2 = " greengrass" ;
71
77
std::string pattern2 = " abc" ;
72
-
73
- std::vector<int > matching_indexes2= find_pat_in_text (pattern2,text2);
78
+
79
+ std::vector<int > matching_indexes2 = find_pat_in_text (pattern2, text2);
74
80
assert ((matching_indexes2 == std::vector<int >{}));
75
81
}
76
82
@@ -79,7 +85,6 @@ static void test(){
79
85
* @returns 0 on exit
80
86
*/
81
87
int main () {
82
-
83
88
test (); // run self-test implementations
84
89
return 0 ;
85
90
}
0 commit comments