Skip to content

Commit 2cfe6d7

Browse files
committed
add Zalgorithm
1 parent e6cb96f commit 2cfe6d7

File tree

1 file changed

+126
-0
lines changed

1 file changed

+126
-0
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
package com.thealgorithms.strings;
2+
3+
/**
4+
* Z Algorithm for Pattern Matching
5+
*
6+
* The Z algorithm finds all occurrences of a pattern in a text in linear time.
7+
* For a string S of length n, the Z array stores the length of the longest substring
8+
* starting from S[i] which is also a prefix of S.
9+
*
10+
* Time Complexity: O(n + m) where n is text length and m is pattern length
11+
* Space Complexity: O(n + m)
12+
*
13+
* Applications:
14+
* - Pattern matching
15+
* - String searching
16+
* - Preprocessing for other string algorithms
17+
*
18+
* @author YourName
19+
*/
20+
public final class ZAlgorithm {
21+
22+
private ZAlgorithm() {
23+
// Utility class
24+
}
25+
26+
/**
27+
* Computes the Z array for given string
28+
* Z[i] = length of longest substring starting from i which is also prefix of string
29+
*
30+
* @param str input string
31+
* @return Z array
32+
*/
33+
public static int[] computeZArray(String str) {
34+
if (str == null || str.isEmpty()) {
35+
return new int[0];
36+
}
37+
38+
int n = str.length();
39+
int[] z = new int[n];
40+
z[0] = n; // First element is always equal to string length
41+
42+
int left = 0;
43+
int right = 0;
44+
45+
for (int i = 1; i < n; i++) {
46+
if (i > right) {
47+
// Outside the current Z-box, compute from scratch
48+
left = right = i;
49+
while (right < n && str.charAt(right - left) == str.charAt(right)) {
50+
right++;
51+
}
52+
z[i] = right - left;
53+
right--;
54+
} else {
55+
// Inside the Z-box, use previously computed values
56+
int k = i - left;
57+
if (z[k] < right - i + 1) {
58+
z[i] = z[k];
59+
} else {
60+
left = i;
61+
while (right < n && str.charAt(right - left) == str.charAt(right)) {
62+
right++;
63+
}
64+
z[i] = right - left;
65+
right--;
66+
}
67+
}
68+
}
69+
70+
return z;
71+
}
72+
73+
/**
74+
* Searches for all occurrences of pattern in text using Z algorithm
75+
*
76+
* @param text the text to search in
77+
* @param pattern the pattern to search for
78+
* @return array of starting indices where pattern is found
79+
*/
80+
public static int[] search(String text, String pattern) {
81+
if (text == null || pattern == null || pattern.isEmpty() || text.length() < pattern.length()) {
82+
return new int[0];
83+
}
84+
85+
// Concatenate pattern and text with a separator
86+
String concat = pattern + "$" + text;
87+
int[] z = computeZArray(concat);
88+
89+
int patternLen = pattern.length();
90+
java.util.List<Integer> results = new java.util.ArrayList<>();
91+
92+
// Find positions where Z value equals pattern length
93+
for (int i = patternLen + 1; i < z.length; i++) {
94+
if (z[i] == patternLen) {
95+
results.add(i - patternLen - 1);
96+
}
97+
}
98+
99+
return results.stream().mapToInt(Integer::intValue).toArray();
100+
}
101+
102+
/**
103+
* Main method for testing
104+
*/
105+
public static void main(String[] args) {
106+
// Test Z array computation
107+
String str = "aabcaabxaaaz";
108+
int[] z = computeZArray(str);
109+
System.out.println("Z array for '" + str + "':");
110+
for (int i = 0; i < z.length; i++) {
111+
System.out.print(z[i] + " ");
112+
}
113+
System.out.println("\n");
114+
115+
// Test pattern matching
116+
String text = "ababcabcabababd";
117+
String pattern = "ababd";
118+
int[] matches = search(text, pattern);
119+
120+
System.out.println("Searching for '" + pattern + "' in '" + text + "'");
121+
System.out.println("Pattern found at indices: ");
122+
for (int index : matches) {
123+
System.out.print(index + " ");
124+
}
125+
}
126+
}

0 commit comments

Comments
 (0)