diff --git a/DIRECTORY.md b/DIRECTORY.md index 042efa72addc..c278b6915d49 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -821,6 +821,7 @@ - 📄 [Upper](src/main/java/com/thealgorithms/strings/Upper.java) - 📄 [ValidParentheses](src/main/java/com/thealgorithms/strings/ValidParentheses.java) - 📄 [WordLadder](src/main/java/com/thealgorithms/strings/WordLadder.java) + - 📄 [ZAlgorithm](src/main/java/com/thealgorithms/strings/ZAlgorithm.java) - 📁 **zigZagPattern** - 📄 [ZigZagPattern](src/main/java/com/thealgorithms/strings/zigZagPattern/ZigZagPattern.java) - 📁 **tree** @@ -1578,6 +1579,7 @@ - 📄 [UpperTest](src/test/java/com/thealgorithms/strings/UpperTest.java) - 📄 [ValidParenthesesTest](src/test/java/com/thealgorithms/strings/ValidParenthesesTest.java) - 📄 [WordLadderTest](src/test/java/com/thealgorithms/strings/WordLadderTest.java) + - 📄 [ZAlgorithmTest](src/test/java/com/thealgorithms/strings/ZAlgorithmTest.java) - 📁 **zigZagPattern** - 📄 [ZigZagPatternTest](src/test/java/com/thealgorithms/strings/zigZagPattern/ZigZagPatternTest.java) - 📁 **tree** diff --git a/src/main/java/com/thealgorithms/strings/ZAlgorithm.java b/src/main/java/com/thealgorithms/strings/ZAlgorithm.java new file mode 100644 index 000000000000..dc029b751f45 --- /dev/null +++ b/src/main/java/com/thealgorithms/strings/ZAlgorithm.java @@ -0,0 +1,48 @@ +/* + * https://en.wikipedia.org/wiki/Z-algorithm + */ +package com.thealgorithms.strings; + +public final class ZAlgorithm { + + private ZAlgorithm() { + throw new UnsupportedOperationException("Utility class"); + } + + public static int[] zFunction(String s) { + int n = s.length(); + int[] z = new int[n]; + int l = 0; + int r = 0; + + for (int i = 1; i < n; i++) { + if (i <= r) { + z[i] = Math.min(r - i + 1, z[i - l]); + } + + while (i + z[i] < n && s.charAt(z[i]) == s.charAt(i + z[i])) { + z[i]++; + } + + if (i + z[i] - 1 > r) { + l = i; + r = i + z[i] - 1; + } + } + + return z; + } + + public static int search(String text, String pattern) { + String s = pattern + "$" + text; + int[] z = zFunction(s); + int p = pattern.length(); + + for (int i = 0; i < z.length; i++) { + if (z[i] == p) { + return i - p - 1; + } + } + return -1; + } +} diff --git a/src/test/java/com/thealgorithms/strings/ZAlgorithmTest.java b/src/test/java/com/thealgorithms/strings/ZAlgorithmTest.java new file mode 100644 index 000000000000..df749ed9a8b5 --- /dev/null +++ b/src/test/java/com/thealgorithms/strings/ZAlgorithmTest.java @@ -0,0 +1,25 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class ZAlgorithmTest { + + @Test + void testZFunction() { + int[] z = ZAlgorithm.zFunction("aaaaa"); + assertArrayEquals(new int[] {0, 4, 3, 2, 1}, z); + } + + @Test + void testSearchFound() { + assertEquals(2, ZAlgorithm.search("abcabca", "cab")); + } + + @Test + void testSearchNotFound() { + assertEquals(-1, ZAlgorithm.search("abcdef", "gh")); + } +}