Find orientation of a pattern in a matrix - GeeksforGeeks

02 Mar, 2022
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. 
C++
C
Java
Python3
C#
Javascript
// 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 patternvoid 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 algorithmvoid 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 Codeint 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 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 patternvoid 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 algorithmvoid 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 functionint 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 program for finding orientation of the pattern // using KMP pattern searching algorithmimport 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 program for finding orientation of the pattern# using KMP pattern searching algorithmN = 5 # Used in KMP Search for preprocessing the patterndef 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 algorithmdef 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 Codemat=[['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# program for finding orientation of// the pattern using KMP pattern searching// algorithmusing 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 algorithmpublic 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 Codestatic 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
<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
This article is contributed by Aditya Goel. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above  
kumar65
mohit kumar 29
avanitrachhadiya2155
rag2127
unknown2108
saurabh1990aror
surinderdawra388
Matrix
Matrix
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Sudoku | Backtracking-7
Divide and Conquer | Set 5 (Strassen's Matrix Multiplication)
Program to multiply two matrices
Inplace rotate square matrix by 90 degrees | Set 1
The Celebrity Problem
Rotate a matrix by 90 degree in clockwise direction without using any extra space
Python program to multiply two matrices
Maximum size rectangle binary sub-matrix with all 1s
Printing all solutions in N-Queen Problem
Count all possible paths from top left to bottom right of a mXn matrix