Open In App

Find orientation of a pattern in a matrix

Last Updated : 24 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a matrix of characters and a pattern, find the orientation of pattern in the matrix. In other words, find if pattern appears in matrix in horizontal or vertical direction. Achieve this in minimum time possible.

Input:
mat[N][N] = { {'a', 'b', 'c', 'd', 'e'},
              {'f', 'g', 'h', 'i', 'j'},
              {'k', 'l', 'm', 'n', 'o'},
              {'p', 'q', 'r', 's', 't'},
              {'u', 'v', 'w', 'x', 'y'}};
pattern = "pqrs";

Output: Horizontal

We strongly recommend you to minimize your browser and try this yourself first.
A simple solution is for each row and column, use Naive pattern searching algorithm to find the orientation of pattern in the matrix. The time complexity of Naive pattern searching algorithm for every row is O(NM) where N is size of the matrix and M is length of the pattern. So, the time complexity of this solution will be O(N*(NM)) as each of N rows and N columns takes O(NM) time.

Can we do better? 
The idea is to use KMP pattern matching algorithm for each row and column. The KMP matching algorithm improves the worst case to O(N + M). The total cost of a KMP search is linear in the number of characters of string and pattern. For a N x N matrix and pattern of length M, complexity of this solution will be O(N*(N+M)) as each of N rows and N columns will take O(N + M) time. 

Implementation:

C++




// C++ program for finding orientation of the pattern 
// using KMP pattern searching algorithm 
#include<bits/stdc++.h>
using namespace std;
#define N 5 
  
// Used in KMP Search for preprocessing the pattern 
void computeLPSArray(char *pat, int M, int *lps) 
    // length of the previous longest prefix suffix 
    int len = 0; 
    int i = 1; 
  
    lps[0] = 0; // lps[0] is always 0 
  
    // the loop calculates lps[i] for i = 1 to M-1 
    while (i < M) 
    
        if (pat[i] == pat[len]) 
        
            len++; 
            lps[i++] = len; 
        
        else // (pat[i] != pat[len]) 
        
            if (len != 0) 
            
                // This is tricky. Consider the example 
                // AAACAAAA and i = 7. 
                len = lps[len - 1]; 
  
                // Also, note that we do not increment i here 
            
            else // if (len == 0) 
            
                lps[i++] = 0; 
            
        
    
  
int KMPSearch(char *pat, char *txt) 
    int M = strlen(pat); 
  
    // create lps[] that will hold the longest 
    // prefix suffix values for pattern 
    int *lps = (int *)malloc(sizeof(int)*M); 
    int j = 0; // index for pat[] 
  
    // Preprocess the pattern (calculate lps[] array) 
    computeLPSArray(pat, M, lps); 
  
    int i = 0; // index for txt[] 
    while (i < N) 
    
        if (pat[j] == txt[i]) 
        
            j++; 
            i++; 
        
        if (j == M) 
        
            // return 1 is pattern is found 
            return 1; 
        
          
        // mismatch after j matches 
        else if (i < N && pat[j] != txt[i]) 
        
            // Do not match lps[0..lps[j-1]] characters, 
            // they will match anyway 
            if (j != 0) 
                j = lps[j - 1]; 
            else
                i = i + 1; 
        
    
    free(lps); // to avoid memory leak 
      
    // return 0 is pattern is not found 
    return 0; 
  
// Function to find orientation of pattern in the matrix 
// It uses KMP pattern searching algorithm 
void findOrientation(char mat[][N], char *pat) 
    // allocate memory for string containing cols 
    char *col = (char*) malloc(N); 
  
    for (int i = 0; i < N; i++) 
    
        // search in row i 
        if (KMPSearch(pat, mat[i])) 
        
            cout << "Horizontal" << endl;
            return
        
  
        // Construct an array to store i'th column 
        for (int j = 0; j < N; j++) 
            col[j] = *(mat[j] + i); 
  
        // Search in column i 
        if (KMPSearch(pat, col)) 
            cout << "Vertical" << endl; 
    
  
    // to avoid memory leak 
    free(col); 
  
// Driver Code
int main() 
    char mat[N][N] = {{'a', 'b', 'c', 'd', 'e'}, 
                      {'f', 'g', 'h', 'i', 'j'}, 
                       {'k', 'l', 'm', 'n', 'o'}, 
                      {'p', 'q', 'r', 's', 't'}, 
                      {'u', 'v', 'w', 'x', 'y'}}; 
    char pat[] = "pqrs"
  
    findOrientation(mat, pat); 
  
    return 0; 
  
// This code is contributed by kumar65


C




// C program for finding orientation of the pattern
// using KMP pattern searching algorithm
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 5
  
// Used in KMP Search for preprocessing the pattern
void computeLPSArray(char *pat, int M, int *lps)
{
    // length of the previous longest prefix suffix
    int len = 0;
    int i = 1;
  
    lps[0] = 0; // lps[0] is always 0
  
    // the loop calculates lps[i] for i = 1 to M-1
    while (i < M)
    {
        if (pat[i] == pat[len])
        {
            len++;
            lps[i++] = len;
        }
        else // (pat[i] != pat[len])
        {
            if (len != 0)
            {
                // This is tricky. Consider the example
                // AAACAAAA and i = 7.
                len = lps[len-1];
  
                // Also, note that we do not increment i here
            }
            else // if (len == 0)
            {
                lps[i++] = 0;
            }
        }
    }
}
  
int KMPSearch(char *pat, char *txt)
{
    int M = strlen(pat);
  
    // create lps[] that will hold the longest prefix suffix
    // values for pattern
    int *lps = (int *)malloc(sizeof(int)*M);
    int j = 0; // index for pat[]
  
    // Preprocess the pattern (calculate lps[] array)
    computeLPSArray(pat, M, lps);
  
    int i = 0; // index for txt[]
    while (i < N)
    {
        if (pat[j] == txt[i])
        {
            j++;
            i++;
        }
        if (j == M)
        {
            // return 1 is pattern is found
            return 1;
        }
        // mismatch after j matches
        else if (i < N && pat[j] != txt[i])
        {
            // Do not match lps[0..lps[j-1]] characters,
            // they will match anyway
            if (j != 0)
                j = lps[j-1];
            else
                i = i+1;
        }
    }
    free(lps); // to avoid memory leak
    // return 0 is pattern is not found
    return 0;
}
  
// Function to find orientation of pattern in the matrix
// It uses KMP pattern searching algorithm
void findOrientation(char mat[][N], char *pat)
{
    // allocate memory for string containing cols
    char *col = (char*) malloc(N);
  
    for (int i = 0; i < N; i++)
    {
        // search in row i
        if (KMPSearch(pat, mat[i]))
        {
            printf("Horizontal\n");
            return;
        }
  
        // Construct an array to store i'th column
        for (int j = 0; j < N; j++)
            col[j] = *(mat[j] + i);
  
        // Search in column i
        if (KMPSearch(pat, col))
            printf("Vertical\n");
    }
  
    // to avoid memory leak
    free(col);
}
  
// Driver program to test above function
int main()
{
    char mat[N][N] =
    {
        {'a', 'b', 'c', 'd', 'e'},
        {'f', 'g', 'h', 'i', 'j'},
        {'k', 'l', 'm', 'n', 'o'},
        {'p', 'q', 'r', 's', 't'},
        {'u', 'v', 'w', 'x', 'y'}
  
    };
    char pat[] = "pqrs";
  
    findOrientation(mat, pat);
  
    return 0;
}


Java




// Java program for finding orientation of the pattern  
// using KMP pattern searching algorithm 
import java.io.*;
import java.util.*;
class GFG
{
  public static int N = 5;
  
  // Used in KMP Search for preprocessing the pattern  
  public static void computeLPSArray(char pat[], 
                                     int M, int lps[])
  {
  
    // length of the previous longest prefix suffix
    int len = 0;  
    int i = 1
    lps[0] = 0; // lps[0] is always 0
  
    // the loop calculates lps[i] for i = 1 to M-1
    while(i < M)
    {
      if(pat[i] == pat[len])
      {
        len++;  
        lps[i++] = len; 
      }
      else    // (pat[i] != pat[len])  
      {
        if(len != 0)
        {
  
          // This is tricky. Consider the example  
          // AAACAAAA and i = 7.  
          len = lps[len - 1]; 
  
          // Also, note that we do not increment i here
        }
        else    // if (len == 0) 
        {
          lps[i++] = 0;
        }
      }
    }
  
  }
  public static int KMPSearch(char pat[], char txt[])
  {
    int M = pat.length;
  
    // create lps[] that will hold the longest  
    // prefix suffix values for pattern  
    int[] lps = new int[M];
    int j = 0; // index for pat[] 
  
    // Preprocess the pattern (calculate lps[] array)  
    computeLPSArray(pat, M, lps);
  
    int i = 0; // index for txt[]
  
    while(i < N)
    {
      if(pat[j] == txt[i])
      {
        j++;
        i++;
      }
      if(j == M)
      {
  
        // return 1 is pattern is found  
        return 1;
      }
  
      // mismatch after j matches  
      else if(i < N && pat[j] != txt[i])
      {
  
        // Do not match lps[0..lps[j-1]] characters,  
        // they will match anyway  
        if(j != 0)
        {
          j = lps[j - 1];
  
        }
        else
        {
          i = i + 1;
        }
      }
    }
  
    // return 0 is pattern is not found
    return 0;
  }
  
  // Function to find orientation of pattern in the matrix  
  // It uses KMP pattern searching algorithm          
  public static void findOrientation(char mat[][], char pat[])
  {
  
    // allocate memory for string containing cols
    char[] col = new char[N];
    for(int i = 0; i < N; i++)
    {
  
      // search in row i
      if(KMPSearch(pat, mat[i]) == 1)
      {
        System.out.println("Horizontal");
        return;
      }
  
      // Construct an array to store i'th column  
      for(int j = 0; j < N; j++)
      {
        col[j] = mat[j][i];
      }
  
      // Search in column i  
      if(KMPSearch(pat, col) == 1)
      {
        System.out.println("Vertical");
      }            
    }
  }
  
  // Driver Code 
  public static void main (String[] args)
  {
    char[][] mat = {
      {'a', 'b', 'c', 'd', 'e'},{'f', 'g', 'h', 'i', 'j'},
      {'k', 'l', 'm', 'n', 'o'},{'p', 'q', 'r', 's', 't'},
      {'u', 'v', 'w', 'x', 'y'}};
    char pat[] = {'p','q','r','s'};
    findOrientation(mat, pat); 
  }
}
  
// This code is contributed by avanitrachhadiya2155


Python3




# Python3 program for finding orientation of the pattern
# using KMP pattern searching algorithm
N = 5
  
# Used in KMP Search for preprocessing the pattern
def computeLPSArray(pat, M, lps):
      
    # length of the previous longest prefix suffix
    lenl = 0
    i = 1
  
    lps[0] = 0 # lps[0] is always 0
  
    # the loop calculates lps[i] for i = 1 to M-1
    while (i < M):
        if (pat[i] == pat[lenl]):
            lenl += 1
            lps[i] = lenl
            i += 1
        else: # (pat[i] != pat[lenl])
            if (lenl != 0) :
                  
                # This is tricky. Consider the example
                # AAACAAAA and i = 7.
                lenl = lps[lenl - 1]
  
                # Also, note that we do not increment i here
              
            # if (lenl == 0)
            else:
                lps[i] = 0
                i += 1
  
def KMPSearch(pat, txt):
    M = len(pat)
  
    # create lps[] that will hold the longest
    # prefix suffix values for pattern
    lps = [0] * M
    j = 0 # index for pat[]
  
    # Preprocess the pattern (calculate lps[] array)
    computeLPSArray(pat, M, lps)
  
    # index for txt[]
    i = 0 
    while (i < N):
        if (pat[j] == txt[i]):
            j += 1
            i += 1
        if (j == M):
              
            # return 1 is pattern is found
            return 1
  
        # mismatch after j matches
        elif (i < N and pat[j] != txt[i]):
              
            # Do not match lps[0..lps[j-1]] characters,
            # they will match anyway
            if (j != 0):
                j = lps[j - 1]
            else:
                i = i + 1
  
    # to amemory leak
  
    # return 0 is pattern is not found
    return 0
  
# Function to find orientation of pattern in the matrix
# It uses KMP pattern searching algorithm
def findOrientation(mat, pat):
      
    # allocate memory for string containing cols
    col = ['a'] * (N)
  
    for i in range(N):
          
        # search in row i
        if (KMPSearch(pat, mat[i])):
            print("Horizontal")
            return
  
        # Construct an array to store i'th column
        for j in range(N):
            col[j] = mat[j][i]
  
        # Search in column i
        if (KMPSearch(pat, col)):
            print("Vertical")
  
# Driver Code
mat=[['a', 'b', 'c', 'd', 'e'],
    ['f', 'g', 'h', 'i', 'j'],
    ['k', 'l', 'm', 'n', 'o'],
    ['p', 'q', 'r', 's', 't'],
    ['u', 'v', 'w', 'x', 'y']]
pat= "pqrs"
  
findOrientation(mat, pat)
  
# This code is contributed by Mohit kumar 29


C#




// C# program for finding orientation of 
// the pattern using KMP pattern searching
// algorithm 
using System;
  
class GFG{
      
public static int N = 5;
  
// Used in KMP Search for preprocessing the pattern  
public static void computeLPSArray(char[] pat,
                                   int M, int[] lps)
{
      
    // Length of the previous longest
    // prefix suffix
    int len = 0;
    int i = 1; 
      
    // lps[0] is always 0
    lps[0] = 0; 
      
    // The loop calculates lps[i] 
    // for i = 1 to M-1
    while (i < M)
    {
        if (pat[i] == pat[len])
        {
            len++;  
            lps[i++] = len; 
        }
        else    // (pat[i] != pat[len])  
        {
            if (len != 0)
            {
                  
                // This is tricky. Consider the
                // example AAACAAAA and i = 7.  
                len = lps[len - 1];
                  
                // Also, note that we do not 
                // increment i here
            }
              
            // If (len == 0)
            else     
            {
                lps[i++] = 0;
            }
        }
    }
}
  
public static int KMPSearch(char[] pat, char[] txt)
{
    int M = pat.Length;
      
    // Create lps[] that will hold the longest  
    // prefix suffix values for pattern  
    int[] lps = new int[M];
    int j = 0; // index for pat[] 
      
    // Preprocess the pattern
    // (calculate lps[] array)  
    computeLPSArray(pat, M, lps);
    int i = 0; // index for txt[]
      
    while (i < N)
    {
        if (pat[j] == txt[i])
        {
            j++;
            i++;
        }
        if (j == M)
        {
              
            // Return 1 is pattern is found  
            return 1;
        }
          
        // Mismatch after j matches
        else if (i < N && pat[j] != txt[i])
        {
              
            // Do not match lps[0..lps[j-1]] 
            // characters, they will match anyway
            if (j != 0)
            {
                j = lps[j - 1];
            }
            else
            {
                i = i + 1;
            }
        }
    }
      
    // Return 0 is pattern is not found
    return 0;
}
  
// Function to find orientation of pattern 
// in the matrix. It uses KMP pattern
// searching algorithm 
public static void findOrientation(char[,] mat,
                                   char[] pat)
{
      
    // Allocate memory for string 
    // containing cols
    char[] col = new char[N];
    for(int i = 0; i < N; i++)
    {
          
        // Allocate memory for string
        // containing rows
        char[] row = new char[(mat.GetLength(1))];
        for(int j = 0; j < mat.GetLength(1); j++)
        {
            row[j] = mat[i, j];
        }
          
        // Search in row i
        if (KMPSearch(pat, row) == 1)
        {
            Console.WriteLine("Horizontal");
            return;
        }
          
        // Construct an array to store
        // i'th column
        for(int j = 0; j < N; j++)
        {
            col[j] = mat[j,i];
        }
          
        // Search in column i  
        if (KMPSearch(pat, col) == 1)
        {
            Console.WriteLine("Vertical");
        }
    }
}
  
// Driver Code 
static public void Main()
{
    char[,] mat = { { 'a', 'b', 'c', 'd', 'e' },
                    { 'f', 'g', 'h', 'i', 'j' },
                    { 'k', 'l', 'm', 'n', 'o' },
                    { 'p', 'q', 'r', 's', 't' },
                    { 'u', 'v', 'w', 'x', 'y' } };
    char[] pat = {'p','q','r','s'};
      
    findOrientation(mat, pat);
}
}
  
//  This code is contributed by rag2127


Javascript




<script>
// Javascript program for finding orientation of the pattern 
// using KMP pattern searching algorithm
      
    let N = 5;
      
     // Used in KMP Search for preprocessing the pattern 
    function computeLPSArray(pat,M,lps)
    {
        // length of the previous longest prefix suffix
    let len = 0; 
    let i = 1;
    lps[0] = 0; // lps[0] is always 0
   
    // the loop calculates lps[i] for i = 1 to M-1
    while(i < M)
    {
      if(pat[i] == pat[len])
      {
        len++; 
        lps[i++] = len;
      }
      else    // (pat[i] != pat[len]) 
      {
        if(len != 0)
        {
   
          // This is tricky. Consider the example 
          // AAACAAAA and i = 7. 
          len = lps[len - 1];
   
          // Also, note that we do not increment i here
        }
        else    // if (len == 0)
        {
          lps[i++] = 0;
        }
      }
    }
    }
      
    function KMPSearch(pat,txt)
    {
        let M = pat.length;
   
    // create lps[] that will hold the longest 
    // prefix suffix values for pattern 
    let lps = new Array(M);
    let j = 0; // index for pat[]
   
    // Preprocess the pattern (calculate lps[] array) 
    computeLPSArray(pat, M, lps);
   
    let i = 0; // index for txt[]
   
    while(i < N)
    {
      if(pat[j] == txt[i])
      {
        j++;
        i++;
      }
      if(j == M)
      {
   
        // return 1 is pattern is found 
        return 1;
      }
   
      // mismatch after j matches 
      else if(i < N && pat[j] != txt[i])
      {
   
        // Do not match lps[0..lps[j-1]] characters, 
        // they will match anyway 
        if(j != 0)
        {
          j = lps[j - 1];
   
        }
        else
        {
          i = i + 1;
        }
      }
    }
   
    // return 0 is pattern is not found
    return 0;
    }
      
    // Function to find orientation of pattern in the matrix 
  // It uses KMP pattern searching algorithm    
    function findOrientation(mat,pat)
    {
        // allocate memory for string containing cols
    let col = new Array(N);
    for(let i = 0; i < N; i++)
    {
   
      // search in row i
      if(KMPSearch(pat, mat[i]) == 1)
      {
        document.write("Horizontal");
        return;
      }
   
      // Construct an array to store i'th column 
      for(let j = 0; j < N; j++)
      {
        col[j] = mat[j][i];
      }
   
      // Search in column i 
      if(KMPSearch(pat, col) == 1)
      {
        document.write("Vertical");
      }           
    }
    }
      
    // Driver Code
    let mat=[['a', 'b', 'c', 'd', 'e'],
    ['f', 'g', 'h', 'i', 'j'],
    ['k', 'l', 'm', 'n', 'o'],
    ['p', 'q', 'r', 's', 't'],
    ['u', 'v', 'w', 'x', 'y']];
      
       let pat= "pqrs";
    findOrientation(mat, pat);
      
    // This code is contributed by unknown2108
</script>


Output

Horizontal

Time complexity: O(n2).
Auxiliary Space: O(m)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads