2

Given two matrices A and B.

Is there efficient or more pythonic way to find if B is a Sub-Matrix of A?

matrix

The code below is worked but I got a Time limit exceeded when the matrix is so big!

Note: The matrix data structure is represented as an array of strings.

[Input]

A=[
'7283455864',
'6731158619',
'8988242643',
'3830589324',
'2229505813',
'5633845374',
'6473530293',
'7053106601',
'0834282956',
'4607924137']

B=[
'9505',
'3845',
'3530']

[Code]

def gridSearch(G, P):
    # Write your code here
    n=len(G)    # Matrix G row number
    m=len(G[0]) # Matrix G col number

    r=len(P)    # Matrix P row number
    c=len(P[0]) # Matrix P col number

    found='NO'
    for i in range(n-r+1):
        for j in range(m-c+1):
            start_row=i
            end_row=i+r
            start_col=j
            end_col=j+c
            sub=[]
            if G[start_row][start_col]==P[0][0]:
                sub=[x[start_col:end_col] for x in G[start_row:end_row] ]
            if (sub==P):
                found='YES'
                #print(i,j)
                
    return(found) 

[Expected Output]

YES
iacob
  • 20,084
  • 6
  • 92
  • 119
AziMez
  • 2,014
  • 1
  • 6
  • 16
  • 1
    Does this answer your question? [Is there a way to find out if A is a submatrix of B?](https://stackoverflow.com/questions/26896687/is-there-a-way-to-find-out-if-a-is-a-submatrix-of-b) – iacob Dec 11 '21 at 13:49
  • Thank you @iacob, but unfortunately, this does not seem to give me the desired result. – AziMez Dec 11 '21 at 13:58

1 Answers1

3

Rather than search on a letter by letter basis as you seem to be doing with your code, I would utilize the ability to search for strings within another string as follows:

def gridSearch(G, P):
    g_sze = len(G)
    p_sze = len(P)
    p_ptr = 0
    for g_ptr, g_row in enumerate(G):
        if P[p_ptr] in g_row:
            p_ptr += 1
            if p_ptr == p_sze:
                return True
        else:
            p_ptr = 0
            if g_sze - g_ptr < p_sze-p_ptr:
                return False

    return False

The above code makes use of two efficiency approaches, first it searches the arrays by rows and secondly it stops searching rows when the ability to match the remaining rows of the smaller array is no longer possible

Given your second example, here is an approach which uses the string search approach and requires column alignment.

def gridSearch2(G, P):
    g_sze = len(G)
    p_sze = len(P)
    candidates = []
    # First scan for possible start postions
    for row in range(g_sze - p_sze + 1):
        idx = 0
        while idx < g_sze - p_sze:
            ptr = G[row].find(P[0], idx)
            if ptr < 0:
                break
            candidates.append((row, ptr+idx))
            idx = idx + ptr + 1
        # test each possible start postion for matching follow on rows
        while len(candidates)  > 0:
        row, idx  = candidates.pop(0);
        rslt = True
        for pr in range(1, p_sze):
            if G[row + pr].find(P[pr], idx) != idx:
                rslt = False
                break
        if rslt:
            return True
    return False    
itprorh66
  • 3,110
  • 4
  • 9
  • 21
  • Thanks for this response. The problem when using **in** at "***search for strings within another string***" is that can't match exactly the matrix shape. look at the attached image: https://ibb.co/fN9kkbz – AziMez Dec 11 '21 at 17:59
  • I updated the answer to provide a solution to your second example – itprorh66 Dec 12 '21 at 18:25