Skip to content

Commit bbcdd5a

Browse files
authored
Merge pull request #3917 from kosuri-indu/add/z-algorithm
Added Z-Algorithm
2 parents 369f44c + fead6c1 commit bbcdd5a

File tree

1 file changed

+172
-0
lines changed

1 file changed

+172
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
---
2+
id: z-algorithm
3+
title: Z-Algorithm
4+
sidebar_label: Z-Algorithm
5+
tags: [python, java, c++, programming, algorithms, dynamic programming, tutorial, in-depth]
6+
description: In this tutorial, we will learn about the Z-Algorithm and its implementation in Python, Java, and C++ with detailed explanations and examples.
7+
---
8+
9+
# Z-Algorithm
10+
11+
The Z-Algorithm is a linear time algorithm used for pattern matching within a string. It is commonly used to compute the Z-array, which provides information about the occurrences of a substring within a string. The Z-array for a string `S` is an array where the `i-th` position represents the length of the longest substring starting from `S[i]` that matches a prefix of `S`.
12+
13+
## Problem Statement
14+
15+
Given a string `S` of length `n`, the Z-array of `S` is an array `Z` of length `n` where `Z[i]` is the length of the longest substring starting from `S[i]` which is also a prefix of `S`.
16+
17+
## Example
18+
19+
For the string `S = "aabcaabxaaaz"`, the Z-array would be `[0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0]`.
20+
21+
## Algorithm
22+
23+
1. Initialize `L` and `R` to 0. These will define the interval `[L, R]` which is the rightmost segment of `S` that matches the prefix of `S`.
24+
2. Iterate over each character in the string and compute the Z-values based on the interval `[L, R]`.
25+
3. If the current index `i` is outside of `[L, R]`, calculate the Z-value directly.
26+
4. If `i` is within `[L, R]`, use previously computed Z-values to determine the Z-value at `i`.
27+
28+
## Code for Z-Algorithm
29+
30+
## Z-Algorithm
31+
32+
The Z-Algorithm is used for string pattern matching and finding the Z-array, which represents the lengths of the longest substrings starting from each position in a string that match the prefix of the string.
33+
34+
### Python Implementation
35+
36+
```python
37+
def compute_z(s):
38+
n = len(s)
39+
z = [0] * n
40+
l, r, k = 0, 0, 0
41+
for i in range(1, n):
42+
if i > r:
43+
l, r = i, i
44+
while r < n and s[r] == s[r - l]:
45+
r += 1
46+
z[i] = r - l
47+
r -= 1
48+
else:
49+
k = i - l
50+
if z[k] < r - i + 1:
51+
z[i] = z[k]
52+
else:
53+
l = i
54+
while r < n and s[r] == s[r - l]:
55+
r += 1
56+
z[i] = r - l
57+
r -= 1
58+
return z
59+
s = "aabcaabxaaaz"
60+
print("Z-array:", compute_z(s))
61+
```
62+
63+
### Java Implementation
64+
65+
```java
66+
public class ZAlgorithm {
67+
public static int[] computeZ(String s) {
68+
int n = s.length();
69+
int[] z = new int[n];
70+
int l = 0, r = 0, k;
71+
for (int i = 1; i < n; i++) {
72+
if (i > r) {
73+
l = r = i;
74+
while (r < n && s.charAt(r) == s.charAt(r - l)) {
75+
r++;
76+
}
77+
z[i] = r - l;
78+
r--;
79+
} else {
80+
k = i - l;
81+
if (z[k] < r - i + 1) {
82+
z[i] = z[k];
83+
} else {
84+
l = i;
85+
while (r < n && s.charAt(r) == s.charAt(r - l)) {
86+
r++;
87+
}
88+
z[i] = r - l;
89+
r--;
90+
}
91+
}
92+
}
93+
return z;
94+
}
95+
96+
public static void main(String[] args) {
97+
String s = "aabcaabxaaaz";
98+
int[] z = computeZ(s);
99+
System.out.print("Z-array: ");
100+
for (int value : z) {
101+
System.out.print(value + " ");
102+
}
103+
}
104+
}
105+
```
106+
107+
### Cpp Implementation
108+
109+
```cpp
110+
#include <iostream>
111+
#include <vector>
112+
#include <string>
113+
114+
using namespace std;
115+
116+
vector<int> computeZ(const string& s) {
117+
int n = s.length();
118+
vector<int> z(n, 0);
119+
int l = 0, r = 0, k;
120+
for (int i = 1; i < n; i++) {
121+
if (i > r) {
122+
l = r = i;
123+
while (r < n && s[r] == s[r - l]) {
124+
r++;
125+
}
126+
z[i] = r - l;
127+
r--;
128+
} else {
129+
k = i - l;
130+
if (z[k] < r - i + 1) {
131+
z[i] = z[k];
132+
} else {
133+
l = i;
134+
while (r < n && s[r] == s[r - l]) {
135+
r++;
136+
}
137+
z[i] = r - l;
138+
r--;
139+
}
140+
}
141+
}
142+
return z;
143+
}
144+
145+
int main() {
146+
string s = "aabcaabxaaaz";
147+
vector<int> z = computeZ(s);
148+
cout << "Z-array: ";
149+
for (int value : z) {
150+
cout << value << " ";
151+
}
152+
cout << endl;
153+
return 0;
154+
}
155+
```
156+
157+
## Output
158+
159+
`Z-array: 0 1 0 3 0 1 0 2 0 1 0 0`
160+
161+
162+
## Time Complexity
163+
164+
The Z-Algorithm runs in $O(n)$ time complexity where `n` is the length of the string. This is due to the linear scan of the string and the efficient handling of previously computed Z-values.
165+
166+
## Space Complexity
167+
168+
The space complexity is $O(n)$ for storing the Z-array.
169+
170+
## Conclusion
171+
172+
The Z-Algorithm is an efficient method for pattern matching and string analysis, providing the Z-array in linear time. This algorithm is widely used in various applications such as substring search and pattern matching.

0 commit comments

Comments
 (0)