Open In App

Count of number of given string in 2D character array

Given a 2-dimensional character array and a string, we need to find the given string in a 2-dimensional character array, such that individual characters can be present left to right, right to left, top to down or down to top.

Examples: 

Input : a ={
{D,D,D,G,D,D},
{B,B,D,E,B,S},
{B,S,K,E,B,K},
{D,D,D,D,D,E},
{D,D,D,D,D,E},
{D,D,D,D,D,G}
}
str= "GEEKS"
Output :1

Input : a = {
{B,B,M,B,B,B},
{C,B,A,B,B,B},
{I,B,G,B,B,B},
{G,B,I,B,B,B},
{A,B,C,B,B,B},
{M,C,I,G,A,M}
}
str= "MAGIC"
Output :3

We have discussed simpler problem to find if a word exists or not in a matrix.
Approach:

  1. To count all occurrences, we can use KMP or Rabin Carp Algorithm. 
  2. Find occ of str in each row and each col as pattern searching in KMP.
  3. Sum all the occ in row and column.

Algorithm : 

  • Step 1- Take each row and convert it into string and apply KMP to find no of occurence of given str in string(for left to right) and its reverse(for right to left).
  • Step 2- sum occurence for each row.
  • Step 3- Apply same for each column. 
  • Step 6- return final answer as summation for column and rows.

Implementation:

// C++ program for implementation of KMP pattern searching
// algorithm

#include <bits/stdc++.h>
using namespace std;
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))

void computeLPSArray(string& pat, int M, vector<int>& lps);

// Prints occurrences of pat[] in txt[]
int KMPSearch(string& pat, string& txt)
{
    int M = pat.size();
    int N = txt.size();

    // create lps[] that will hold the longest prefix suffix
    // values for pattern
    vector<int> lps(M, 0);

    // Preprocess the pattern (calculate lps[] array)
    computeLPSArray(pat, M, lps);
    int i = 0; // index for txt[]
    int j = 0; // index for pat[]
    int cnt = 0; // to store no of occurence.
    while ((N - i) >= (M - j)) {
        if (pat[j] == txt[i]) {
            j++;
            i++;
        }

        if (j == M) {
            cnt++;
            j = lps[j - 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 cnt;
}

// Fills lps[] for given pattern pat[0..M-1]
void computeLPSArray(string& pat, int M, vector<int>& lps)
{
    // length of the previous longest prefix suffix
    int len = 0;

    lps[0] = 0; // lps[0] is always 0

    // the loop calculates lps[i] for i = 1 to M-1
    int i = 1;
    while (i < M) {
        if (pat[i] == pat[len]) {
            len++;
            lps[i] = len;
            i++;
        }
        else // (pat[i] != pat[len])
        {
            if (len != 0) {
                len = lps[len - 1];

                // Also, note that we do not increment
                // i here
            }
            else // if (len == 0)
            {
                lps[i] = 0;
                i++;
            }
        }
    }
}

int main()
{
    string str = "MAGIC";
    string input[] = { "BBABBM", "CBMBBA", "IBABBG",
                       "GOZBBI", "ABBBBC", "MCIGAM" };
    int n = ARRAY_SIZE(input);
    int m = input[0].size();
    int ans = 0;
    // row wise
    for (int i = 0; i < n; i++) {
        string text = input[i];
        // left to right match
        ans += KMPSearch(str, text);
        // right to left match
        reverse(text.begin(), text.end());
        ans += KMPSearch(str, text);
    }

    // column wise;
    for (int i = 0; i < m; i++) {
        string text;
        for (int j = 0; j < n; j++) {
            text.push_back(input[j][i]);
        }
        // top to down;
        ans += KMPSearch(str, text);
        // down to top;
        reverse(text.begin(), text.end());
        ans += KMPSearch(str, text);
    }

    cout << "Count : " << ans << endl;
    return 0;
}



Output
count: 3

Time Complexity: 2*(n1*n2) + m*(n1+n2) => O(n1*n2)

where n1 is the row size and n2 is column size and m is the str size where m <= min(n1,n2)

else, if (m > n1) we don't need to check rows or (m > n2) we don't need to check columns.


Auxiliary Space: O(n1*n2)

Article Tags :