📜  用于矩阵模式搜索的Rabin-Karp算法

📅  最后修改于: 2021-05-05 00:00:02             🧑  作者: Mango

给定尺寸为m1 x m2的矩阵txt [] []和尺寸为n1 x n2的模式pat [] [] ,任务是检查矩阵中是否存在某个模式,如果是,则打印od的顶部mot索引。 txt [] []中的pat [] [] 。假设m1,m2≥n1,n2

例子:

输入: txt [] [] = {{G,H,I,P} {J,K,L,Q} {R,G,H,I} {S,J,K,L}} pat [] [ ] = {{G,H,I},{J,K,L}}输出:在(0,0)找到的模式在(2,1)找到的模式说明: 输入: txt [] [] = {{A,B,C},{D,E,F},{G,H,I}} pat [] [] = {{E,F},{H,I输出:在(1,1)找到的模式

方法:为了使用Rabin-Karp算法在二维数组中查找模式,请考虑输入矩阵txt [m1] [m2]和模式pat [n1] [n2] 。这个想法是找到mat [] []pat [] []的每一列的哈希值,并比较哈希值。对于任何列,如果哈希值等于,则检查相应的行值。步骤如下:

  1. txt [] []pat [] []矩阵中找到前N1行的每一列的哈希值。
  2. 通过为步骤1中找到的列哈希查找哈希值来应用Rabin-Karp算法。
  3. 如果找到匹配项,则比较特定行和列的txt [] []pat [] []矩阵。
  4. 否则,使用滚动哈希将txt矩阵中的列哈希值向下滑动1行。
  5. 重复步骤2至4对所有的哈希值,如果我们发现任何拍拍[] []匹配在TXT [] []然后打印最上面的单元格的指数在TXT [] []。

查找哈希值:为了使用滚动哈希在文本中找到大小为N的子字符串的哈希值,请执行以下步骤:

  1. 从字符串删除第一个字符: hash(txt [s:s + n-1])-(radix **(n-1)* txt [s])%prime_number
  2. 将下一个字符添加到字符串: hash(txt [s:s + n-1])* radix + txt [n]

下面是上述方法的实现:

Python3
# Python implementation for the 
# pattern matching in 2-D matrix
  
# Function to find the hash-value 
# of the given columns of text
def findHash(arr, col, row):
    hashCol = []
    add = 0
    radix = 256
  
    # For each column
    for i in range(0, col):
  
        for j in reversed(range(0, row)):
            add = add + (radix**(row-j-1) * 
                         ord(arr[j][i]))% 101
        hashCol.append(add % 101);
        add = 0
    return hashCol
  
# Function to check equality of the 
# two strings
def checkEquality(txt, row, col, flag):
    txt = [txt[i][col:patCol + col] 
           for i in range(row, patRow + row)]
  
# If pattern found
    if txt == pat:
        flag = 1
        print("Pattern found at", \
              "(", row, ", ", col, ")")
    return flag
      
# Function to find the hash value of
# of the next column using rolling-hash
# of the Rabin-karp
def colRollingHash(txtHash, nxtRow):
  
    radix = 256
  
    # Find the hash of the matrix
    for j in range(len(txtHash)):
        txtHash[j] = (txtHash[j]*radix \
                      + ord(txt[nxtRow][j]))% 101
        txtHash[j] = txtHash[j] - (radix**(patRow) * 
                     ord(txt[nxtRow-patRow][j]))% 101 
        txtHash[j] = txtHash[j]% 101
    return txtHash
      
  
# Function to match a pattern in 
# the given 2D Matrix
def search(txt, pat):
      
# List of the hashed value for
    # the text and pattern columns
    patHash = []
    txtHash = []
  
    # Hash value of the 
    # pat_hash and txt_hash
    patVal = 0
    txtVal = 0 
  
    # Radix value for the input characters
    radix = 256
      
    # Variable to determine if
    # pattern was found or not
    flag = 0
      
    # Function call to find the
    # hash value of columns
    txtHash = findHash(txt, txtCol, patRow)  
    patHash = findHash(pat, patCol, patRow)
      
    # Calculate hash value for patHash
    for i in range(len(patHash)):
        patVal = patVal \
                 + (radix**(len(patHash)-i-1) * 
                 patHash[i]% 101)
    patVal = patVal % 101
      
      
    # Applying Rabin-Karp to compare
    # txtHash and patHash
    for i in range(patRow-1, txtRow):
        col = 0
        txtVal = 0
          
        # Find the hash value txtHash 
        for j in range(len(patHash)):
            txtVal = txtVal\
                     + (radix**(len(patHash)-j-1) * 
                     txtHash[j])% 101
        txtVal = txtVal % 101
          
        if txtVal == patVal:
            flag = checkEquality(\
                     txt, i + 1-patRow, col, flag)
              
        else:
  
            # Roll the txt window by one character 
            for k in range(len(patHash), len(txtHash)):
  
                txtVal = txtVal \
                         * radix + (txtHash[k])% 101
                txtVal = txtVal \
                         - (radix**(len(patHash)) *
                         (txtHash[k-len(patHash)]))% 101
                txtVal = txtVal % 101
                col = col + 1
  
                # Check if txtVal and patVal are equal
                if patVal == txtVal:
                    flag = checkEquality(\
                           txt, i + 1-patRow, col, flag)   
                else:
                    continue
                  
        # To make sure i does not exceed txtRow
        if i + 1


输出:
Pattern found at ( 1 ,  1 )
Prim的算法(邻接矩阵表示的简单实现)
9月18日,06
Kruskal算法(邻接矩阵的简单实现)
9月18日,07
Freivald算法,检查矩阵是否为两个的乘积
3月18日,01