Count of number of given string in 2D character array
Last Updated :
21 May, 2024
Improve
Try it on GfG Practice
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:
- To count all occurrences, we can use KMP or Rabin Carp Algorithm.
- Find occ of str in each row and each col as pattern searching in KMP.
- 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;
}
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 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()
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)