给定维度为m1 x m2 的矩阵txt[][]和维度为n1 x n2 的模式pat[][] ,任务是检查矩阵中是否存在模式,如果是,则打印最上面的索引txt[][] 中的pat[ ][] 。假设m1, m2 ≥ n1, n2
例子:
Input:
txt[][] = {{G, H, I, P}
{J, K, L, Q}
{R, G, H, I}
{S, J, K, L}
}
pat[][] = {{G, H, I},
{J, K, L}
}
Output:
Pattern found at ( 0, 0 )
Pattern found at ( 2, 1 )
Explanation:
Input:
txt[][] = { {A, B, C},
{D, E, F},
{G, H, I}
}
pat[][] = { {E, F},
{H, I}
}
Output:
Pattern found at (1, 1)
方法:为了使用 Rabin-Karp 算法在二维数组中找到模式,请考虑输入矩阵txt[m1][m2]和模式pat[n1][n2] 。这个想法是找到mat[][]和pat[][]的每一列的哈希值并比较哈希值。对于任何列,如果哈希值等于,则检查相应的行值。以下是步骤:
- 找出txt[][]和pat[][]矩阵中前N1行的每一列的哈希值。
- 通过查找在步骤 1 中找到的列哈希的哈希值来应用 Rabin-Karp 算法。
- 如果找到匹配项,则比较特定行和列的txt[][]和pat[][]矩阵。
- 否则,使用滚动散列将 txt 矩阵中的列散列向下滑动 1 行。
- 重复步骤2至4对所有的哈希值,如果我们发现任何拍拍[] []匹配在TXT [] []然后打印最上面的单元格的指数在TXT [] []。
查找散列值:为了使用滚动散列在文本中查找大小为N的子串的散列值,请执行以下步骤:
- 从字符串删除第一个字符: hash(txt[s:s+n-1])-(radix**(n-1)*txt[s])%prime_number
- 将下一个字符添加到字符串: hash(txt[s:s+n-1])*radix + txt[n]
下面是上述方法的实现:
C++
#include
using namespace std;
long long mod = 257; //The modular value
long long r = 256; //radix
long long dr = 1; //Highest power for row hashing
long long dc = 1; //Highest power for col hashing
//func that return a power n under mod m in LogN
long long power(int a,int n,long long m){
if(n == 0){
return 1;
}
if(n == 1){
return a%m;
}
long long pow = power(a,n/2,m);
if(n&1){
return ((a%m)*(pow)%m * (pow)%m)%m;
}
else{
return ((pow)%m * (pow)%m)%m;
}
}
//Checks if all values of pattern matches with the text
bool check(vector> &txt,vector> &pat, long long r,long long c){
for(long long i=0;i findHash(vector> &mat,long long row){
vector hash;
long long col = mat[0].size();
for(long long i=0;i > &txt, vector &t_hash, long long row, long long p_row){
for(long long i=0;i> &txt, vector> &pat){
long long t_row = txt.size();
long long t_col = txt[0].size();
long long p_row = pat.size();
long long p_col = pat[0].size();
dr = power(r,p_row-1,mod);
dc = power(r,p_col-1,mod);
vector t_hash = findHash(txt,p_row); //column hash of p_row rows
vector p_hash = findHash(pat,p_row); //column hash of p_row rows
long long p_val = 0; //hash of entire pattern matrix
for(long long i=0;i> txt{{'A','B','C','D','E'},{'A','B','C','D','E'},{'A','B','C','D','E'},{'A','B','C','D','E'},{'A','B','C','D','E'}};
vector> pat{{'A','B','C','D','E'},{'A','B','C','D','E'},{'A','B','C','D','E'},{'A','B','C','D','E'}};
//function prints the indices of row and col where its a match in txt
rabinKarp(txt,pat);
return 0;
}
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 )
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。