Skip to content
Related Articles

Related Articles

Improve Article

Find starting index for every occurrence of given array B in array A using Z-Algorithm

  • Last Updated : 31 May, 2021

Given two arrays A and B, the task is to find the starting index for every occurrence of array B in array A using Z-Algorithm.
Examples: 
 

Input: A = {1, 2, 3, 2, 3}, B = {2, 3} 
Output: 1 3 
Explanation: 
In array A, array B occurs at index 1 and index 3. Thus the answer is {1, 3}.
Input: A = {1, 1, 1, 1, 1}, B = {1} 
Output: 0 1 2 3 4 
In array A, array B occur at the index {0, 1, 2, 3, 4}. 
 

 

In Z-Algorithm, we construct a Z-Array.
What is Z-Array?
For a arr[0..n-1], Z array is an array, of the same length as the string array arr, where each element Z[i] of Z array stores length of the longest substring starting from arr[i] which is also a prefix of arr[0..n-1]. The first entry of Z array is meaningless as complete array is always prefix of itself.
For example: For a given array arr[] = { 1, 2, 3, 0, 1, 2, 3, 5} 
 



Approach: 
 

  • Merge array B and array A with a separator in between into a new array C. Here separator can be any special character.
  • Create Z-array using array C.
  • Iterate over the Z-array and print all those indices whose value is greater than or equal to the length of the array B.

Below is the implementation of the above approach. 
 

C++




// CPP implementation for pattern
// searching in an array using Z-Algorithm
#include<bits/stdc++.h>
using namespace std;
 
// Function to calculate Z-Array
vector<int> zArray(vector<int> arr)
{
    int n = arr.size();
    vector<int> z(n);
    int r = 0, l = 0;
 
    // Loop to calculate Z-Array
    for (int k = 1; k < n; k++) {
 
        // Outside the Z-box
        if (k > r) {
            r = l = k;
            while (r < n
                && arr[r] == arr[r - l])
                r++;
            z[k] = r - l;
            r--;
        }
 
        // Inside Z-box
        else {
            int k1 = k - l;
 
            if (z[k1] < r - k + 1)
                z[k] = z[k1];
 
            else {
                l = k;
                while (r < n
                    && arr[r] == arr[r - l])
                    r++;
                z[k] = r - l;
                r--;
            }
        }
    }
    return z;
}
 
// Helper function to merge two
// arrays and create a single array
vector<int> mergeArray(vector<int> A, vector<int> B)
{
    int n = A.size();
    int m = B.size();
    vector<int> z;
 
    // Array to store merged array
    vector<int> c(n + m + 1);
 
    // Copying array B
    for (int i = 0; i < m; i++)
        c[i] = B[i];
 
    // Adding a separator
    c[m] = INT_MAX;
 
    // Copying array A
    for (int i = 0; i < n; i++)
        c[m + i + 1] = A[i];
 
    // Calling Z-function
    z = zArray(c);
    return z;
}
 
// Function to help compute the Z array
void findZArray(vector<int>A,vector<int>B, int n)
{
    int flag = 0;
    vector<int> z;
    z = mergeArray(A, B);
 
    // Printing indexes where array B occur
    for (int i = 0; i < z.size(); i++) {
        if (z[i] == n) {
 
            cout << (i - n - 1) << " ";
            flag = 1;
        }
    }
    if (flag == 0) {
        cout << ("Not Found");
    }
}
 
// Driver Code
int main()
{
    vector<int>A{ 1, 2, 3, 2, 3, 2 };
    vector<int>B{ 2, 3 };
    int n = B.size();
 
    findZArray(A, B, n);
}
 
// This code is contributed by Surendra_Gangwar

Java




// Java implementation for pattern
// searching in an array using Z-Algorithm
 
import java.io.*;
import java.util.*;
 
class GfG {
 
    // Function to calculate Z-Array
    private static int[] zArray(int arr[])
    {
        int z[];
        int n = arr.length;
        z = new int[n];
        int r = 0, l = 0;
 
        // Loop to calculate Z-Array
        for (int k = 1; k < n; k++) {
 
            // Outside the Z-box
            if (k > r) {
                r = l = k;
                while (r < n
                       && arr[r] == arr[r - l])
                    r++;
                z[k] = r - l;
                r--;
            }
 
            // Inside Z-box
            else {
                int k1 = k - l;
 
                if (z[k1] < r - k + 1)
                    z[k] = z[k1];
 
                else {
                    l = k;
                    while (r < n
                           && arr[r] == arr[r - l])
                        r++;
                    z[k] = r - l;
                    r--;
                }
            }
        }
        return z;
    }
 
    // Helper function to merge two
    // arrays and create a single array
    private static int[] mergeArray(int A[],
                                    int B[])
    {
        int n = A.length;
        int m = B.length;
        int z[];
 
        // Array to store merged array
        int c[] = new int[n + m + 1];
 
        // Copying array B
        for (int i = 0; i < m; i++)
            c[i] = B[i];
 
        // Adding a separator
        c[m] = Integer.MAX_VALUE;
 
        // Copying array A
        for (int i = 0; i < n; i++)
            c[m + i + 1] = A[i];
 
        // Calling Z-function
        z = zArray(c);
        return z;
    }
 
    // Function to help compute the Z array
    private static void findZArray(int A[], int B[], int n)
    {
        int flag = 0;
        int z[];
        z = mergeArray(A, B);
 
        // Printing indexes where array B occur
        for (int i = 0; i < z.length; i++) {
            if (z[i] == n) {
 
                System.out.print((i - n - 1)
                                 + " ");
                flag = 1;
            }
        }
        if (flag == 0) {
            System.out.println("Not Found");
        }
    }
 
    // Driver Code
    public static void main(String args[])
    {
        int A[] = { 1, 2, 3, 2, 3, 2 };
        int B[] = { 2, 3 };
        int n = B.length;
 
        findZArray(A, B, n);
    }
}

Python3




# Python3 implementation for pattern
# searching in an array using Z-Algorithm
import sys;
 
# Function to calculate Z-Array
def zArray(arr) :
    n = len(arr);
    z = [0]*n;
    r = 0;
    l = 0;
     
    # Loop to calculate Z-Array
    for k in range(1, n) :
         
        # Outside the Z-box
        if (k > r) :
            r = l = k;
            while (r < n and arr[r] == arr[r - l]) :
                r += 1;
            z[k] = r - l;
            r -= 1;
                 
        # Inside Z-box
        else :
            k1 = k - l;
             
            if (z[k1] < r - k + 1) :
                z[k] = z[k1];
                 
            else :
                l = k;
                while (r < n and arr[r] == arr[r - l]) :
                    r += 1 ;
                z[k] = r - l;
                r -= 1;
                     
    return z;
 
# Helper function to merge two
# arrays and create a single array
def mergeArray(A,B) :
 
    n = len(A);
    m = len(B);
 
    # Array to store merged array
    c = [0]*(n + m + 1);
 
    # Copying array B
    for i in range(m) :
        c[i] = B[i];
 
    # Adding a separator
    c[m] = sys.maxsize;
 
    # Copying array A
    for i in range(n) :
        c[m + i + 1] = A[i];
 
    # Calling Z-function
    z = zArray(c);
    return z;
 
# Function to help compute the Z array
def findZArray( A,B, n) :
    flag = 0;
    z = mergeArray(A, B);
     
    # Printing indexes where array B occur
    for i in range(len(z)) :
        if (z[i] == n) :
            print(i - n - 1, end= " ");
            flag = 1;
             
    if (flag == 0) :
        print("Not Found");
 
# Driver Code
if __name__ == "__main__" :
     
    A = [ 1, 2, 3, 2, 3, 2];
    B = [ 2, 3 ];
    n = len(B);
    findZArray(A, B, n);
 
# This code is contributed by AnkitRai01

C#




// C# implementation for pattern
// searching in an array using Z-Algorithm
using System;
 
class GfG
{
 
    // Function to calculate Z-Array
    private static int[] zArray(int []arr)
    {
        int []z;
        int n = arr.Length;
        z = new int[n];
        int r = 0, l = 0;
 
        // Loop to calculate Z-Array
        for (int k = 1; k < n; k++)
        {
 
            // Outside the Z-box
            if (k > r)
            {
                r = l = k;
                while (r < n
                    && arr[r] == arr[r - l])
                    r++;
                z[k] = r - l;
                r--;
            }
 
            // Inside Z-box
            else
            {
                int k1 = k - l;
 
                if (z[k1] < r - k + 1)
                    z[k] = z[k1];
 
                else
                {
                    l = k;
                    while (r < n
                        && arr[r] == arr[r - l])
                        r++;
                    z[k] = r - l;
                    r--;
                }
            }
        }
        return z;
    }
 
    // Helper function to merge two
    // arrays and create a single array
    private static int[] mergeArray(int []A,
                                    int []B)
    {
        int n = A.Length;
        int m = B.Length;
        int []z;
 
        // Array to store merged array
        int []c = new int[n + m + 1];
 
        // Copying array B
        for (int i = 0; i < m; i++)
            c[i] = B[i];
 
        // Adding a separator
        c[m] = int.MaxValue;
 
        // Copying array A
        for (int i = 0; i < n; i++)
            c[m + i + 1] = A[i];
 
        // Calling Z-function
        z = zArray(c);
        return z;
    }
 
    // Function to help compute the Z array
    private static void findZArray(int []A, int []B, int n)
    {
        int flag = 0;
        int []z;
        z = mergeArray(A, B);
 
        // Printing indexes where array B occur
        for (int i = 0; i < z.Length; i++)
        {
            if (z[i] == n)
            {
 
                Console.Write((i - n - 1)
                                + " ");
                flag = 1;
            }
        }
        if (flag == 0)
        {
            Console.WriteLine("Not Found");
        }
    }
 
    // Driver Code
    public static void Main()
    {
        int []A = { 1, 2, 3, 2, 3, 2 };
        int []B = { 2, 3 };
        int n = B.Length;
 
        findZArray(A, B, n);
    }
}
 
// This code is contributed by AnkitRai01

Javascript




<script>
 
// JavaScript implementation for pattern
// searching in an array using Z-Algorithm
 
 
// Function to calculate Z-Array
function zArray(arr) {
    let n = arr.length;
    let z = new Array(n);
    let r = 0, l = 0;
 
    // Loop to calculate Z-Array
    for (let k = 1; k < n; k++) {
 
        // Outside the Z-box
        if (k > r) {
            r = l = k;
            while (r < n
                && arr[r] == arr[r - l])
                r++;
            z[k] = r - l;
            r--;
        }
 
        // Inside Z-box
        else {
            let k1 = k - l;
 
            if (z[k1] < r - k + 1)
                z[k] = z[k1];
 
            else {
                l = k;
                while (r < n
                    && arr[r] == arr[r - l])
                    r++;
                z[k] = r - l;
                r--;
            }
        }
    }
    return z;
}
 
// Helper function to merge two
// arrays and create a single array
function mergeArray(A, B) {
    let n = A.length;
    let m = B.length;
    let z = new Array();
 
    // Array to store merged array
    let c = new Array(n + m + 1);
 
    // Copying array B
    for (let i = 0; i < m; i++)
        c[i] = B[i];
 
    // Adding a separator
    c[m] = Number.MAX_SAFE_INTEGER;
 
    // Copying array A
    for (let i = 0; i < n; i++)
        c[m + i + 1] = A[i];
 
    // Calling Z-function
    z = zArray(c);
    return z;
}
 
// Function to help compute the Z array
function findZArray(A, B, n) {
    let flag = 0;
    let z = [];
    z = mergeArray(A, B);
 
    // Printing indexes where array B occur
    for (let i = 0; i < z.length; i++) {
        if (z[i] == n) {
 
            document.write((i - n - 1) + " ");
            flag = 1;
        }
    }
    if (flag == 0) {
        document.write("Not Found");
    }
}
 
// Driver Code
 
let A = [1, 2, 3, 2, 3, 2];
let B = [2, 3];
let n = B.length;
 
findZArray(A, B, n);
 
// This code is contributed by gfgking
 
</script>
Output: 
1 3

 

Time Complexity: O(N + M).
 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :