Open In App

Count of number of given string in 2D character array

Last Updated : 21 May, 2024
Suggest changes
Share
Like Article
Like
Report

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++
// 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; } 
Java
import java.util.*; class KMPStringMatching {  // Prints occurrences of pat[] in txt[]  static int KMPSearch(String pat, String txt)  {  int M = pat.length();  int N = txt.length();  // create lps[] that will hold the longest prefix  // suffix values for pattern  int[] lps = new int[M];  computeLPSArray(pat, M, lps);  int i = 0; // index for txt[]  int j = 0; // index for pat[]  int cnt = 0; // to store no of occurrence  while ((N - i) >= (M - j)) {  if (pat.charAt(j) == txt.charAt(i)) {  j++;  i++;  }  if (j == M) {  cnt++;  j = lps[j - 1];  }  // mismatch after j matches  else if (i < N  && pat.charAt(j) != txt.charAt(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]  static void computeLPSArray(String pat, int M,  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.charAt(i) == pat.charAt(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++;  }  }  }  }  public static void main(String[] args)  {  String str = "MAGIC";  String[] input = { "BBABBM", "CBMBBA", "IBABBG",  "GOZBBI", "ABBBBC", "MCIGAM" };  int n = input.length;  int m = input[0].length();  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  ans += KMPSearch(str, new StringBuilder(text)  .reverse()  .toString());  }  // column wise;  for (int i = 0; i < m; i++) {  StringBuilder text = new StringBuilder();  for (int j = 0; j < n; j++) {  text.append(input[j].charAt(i));  }  // top to down;  ans += KMPSearch(str, text.toString());  // down to top;  ans += KMPSearch(str,  text.reverse().toString());  }  System.out.println("Count : " + ans);  } } 
Python
# Python program for implementation of KMP pattern searching algorithm def computeLPSArray(pat, M, lps): # length of the previous longest prefix suffix len = 0 lps[0] = 0 # lps[0] is always 0 # the loop calculates lps[i] for i = 1 to M-1 i = 1 while i < M: if pat[i] == pat[len]: len += 1 lps[i] = len i += 1 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 += 1 # Prints occurrences of pat in txt def KMPSearch(pat, txt): M = len(pat) N = len(txt) # create lps[] that will hold the longest prefix suffix values for pattern lps = [0]*M # Preprocess the pattern (calculate lps[] array) computeLPSArray(pat, M, lps) i = 0 # index for txt j = 0 # index for pat cnt = 0 # to store no of occurence. while (N - i) >= (M - j): if pat[j] == txt[i]: j += 1 i += 1 if j == M: cnt += 1 j = lps[j - 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 return cnt def main(): str = "MAGIC" input = ["BBABBM", "CBMBBA", "IBABBG", "GOZBBI", "ABBBBC", "MCIGAM"] n = len(input) m = len(input[0]) ans = 0 # row wise for i in range(n): text = input[i] # left to right match ans += KMPSearch(str, text) # right to left match text = text[::-1] ans += KMPSearch(str, text) # column wise; for i in range(m): text = "" for j in range(n): text += input[j][i] # top to down; ans += KMPSearch(str, text) # down to top; text = text[::-1] ans += KMPSearch(str, text) print("Count : ", ans) if __name__ == "__main__": main() 
JavaScript
function computeLPSArray(pat, M, lps) {  let len = 0;  lps[0] = 0;  let i = 1;  while (i < M) {  if (pat[i] === pat[len]) {  len++;  lps[i] = len;  i++;  } else {  if (len !== 0) {  len = lps[len - 1];  } else {  lps[i] = 0;  i++;  }  }  } } function KMPSearch(pat, txt) {  let M = pat.length;  let N = txt.length;  let lps = new Array(M).fill(0);  computeLPSArray(pat, M, lps);  let i = 0, j = 0, cnt = 0;  while (N - i >= M - j) {  if (pat[j] === txt[i]) {  j++;  i++;  }  if (j === M) {  cnt++;  j = lps[j - 1];  } else if (i < N && pat[j] !== txt[i]) {  if (j !== 0) {  j = lps[j - 1];  } else {  i++;  }  }  }  return cnt; } function main() {  let str = "MAGIC";  let input = ["BBABBM", "CBMBBA", "IBABBG", "GOZBBI", "ABBBBC", "MCIGAM"];  let n = input.length;  let m = input[0].length;  let ans = 0;  for (let i = 0; i < n; i++) {  let text = input[i];  ans += KMPSearch(str, text);  text = text.split('').reverse().join('');  ans += KMPSearch(str, text);  }  for (let i = 0; i < m; i++) {  let text = '';  for (let j = 0; j < n; j++) {  text += input[j][i];  }  ans += KMPSearch(str, text);  text = text.split('').reverse().join('');  ans += KMPSearch(str, text);  }  console.log("Count : " + ans); } main(); 

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)


Similar Reads