给定文本和通配符模式,请查找通配符模式是否与文本匹配。匹配项应覆盖整个文本(而不是部分文本)。
通配符模式可以包含字符“?”和 ‘*’:
- ‘?’ –匹配任何单个字符
- ‘*’–匹配任何字符序列(包括空序列)
先决条件:动态编程|通配符模式匹配
例子:
Text = "baaabab",
Pattern = “*****ba*****ab", output : true
Pattern = "baaa?ab", output : true
Pattern = "ba*a?", output : true
Pattern = "a*ab", output : false
每次出现“?”通配符模式中的字符可以用任何其他字符替换,并且每次出现*时都可以使用一系列字符,以使通配符模式在替换后变得与输入字符串相同。
我们在这里讨论了具有O(mxn)时间和O(mxn)空间复杂度的解决方案。
对于应用优化,我们将首先注意到BASE CASE ,它说,如果模式的长度为零,那么只有当我们必须与模式匹配的文本的长度也为零时,答案才是正确的。
算法:
- 让我成为指向文本当前字符的标记。
令j为指向模式当前字符的标记。
令index_txt为标记,以指向在模式中遇到“ *”的文本字符。
令index_pat为指向模式中“ *”位置的标记。 - 在任何时候,如果我们观察到txt [i] == pat [j],那么我们将i和j都增加,因为在这种情况下不需要执行任何操作。
- 如果遇到pat [j] ==’?’,则类似于步骤–(2)中提到的情况为’?’具有与任何单个字符匹配的属性。
- 如果遇到pat [j] ==’*’,则我们更新index_txt和index_pat的值,因为’*’具有匹配任意字符序列(包括空序列)的属性,并且我们将j的值递增为比较模式的下一个字符与文本的当前字符。 (因为由i表示的字符尚未得到答复)。
- 现在,如果txt [i] == pat [j],并且我们之前遇到过’*’,则意味着’*’包含空序列,否则,如果txt [i]!= pat [j],则为字符需要由“ *”提供,以便进行当前字符匹配,然后我需要在回答时将其递增,但仍然需要回答由j表示的字符,因此,j = index_pat + 1,i = index_txt +1(因为’*’也可以捕获其他字符),index_txt ++(因为文本中的当前字符已匹配)。
- 如果步骤–(5)无效,这意味着txt [i]!= pat [j],那么我们也没有遇到过’*’,这意味着该模式不可能与字符串匹配。 (返回假)。
- 检查j是否达到其最终值,然后返回最终答案。
让我们看一下上面的算法,然后转到编码部分:
文字=“ baaabab”
模式=“ ***** ba ***** ab”
现在应用算法
步骤–(1):i = 0(i –>’b’)
j = 0(j –>’*’)
index_txt = -1
index_pat = -1
注意:循环将一直运行到我最终完成
价值或答案成为错误中途。
第一次比较:
正如我们在这里看到的,pat [j] ==’*’,因此直接跳至步骤–(4)。
步骤–(4):index_txt = i(index_txt –>’b’)
index_pat = j(index_pat –>’*’)
j ++(j –>’*’)
经过四次比较:i = 0(i –>’b’)
j = 5(j –>’b’)
index_txt = 0(index_txt –>’b’)
index_pat = 4(index_pat –>’*’)
第六次比较:-
正如我们在这里看到的txt [i] == pat [j],但是我们已经在步骤–(5)中遇到了’*’。
步骤–(5):i = 1(i –>’a’)
j = 6(j –>’a’)
index_txt = 0(index_txt –>’b’)
index_pat = 4(index_pat –>’*’)
第七次比较:-
步骤–(5):i = 2(i –>’a’)
j = 7(j –>’*’)
index_txt = 0(index_txt –>’b’)
index_pat = 4(index_pat –>’*’)
比较:-
步骤–(4):i = 2(i –>’a’)
j = 8(j –>’*’)
index_txt = 2(index_txt –>’a’)
index_pat = 7(index_pat –>’*’)
经过四次比较:i = 2(i –>’a’)
j = 12(j –>’a’)
index_txt = 2(index_txt –>’a’)
index_pat = 11(index_pat –>’*’)
第三比较:-
步骤–(5):i = 3(i –>’a’)
j = 13(j –>’b’)
index_txt = 2(index_txt –>’a’)
index_pat = 11(index_pat –>’*’)
第四次比较:-
步骤–(5):i = 3(i –>’a’)
j = 12(j –>’a’)
index_txt = 3(index_txt –>’a’)
index_pat = 11(index_pat –>’*’)
第十五次比较:-
步骤–(5):i = 4(i –>’b’)
j = 13(j –>’b’)
index_txt = 3(index_txt –>’a’)
index_pat = 11(index_pat –>’*’)
第六比较:-
步骤–(5):i = 5(i –>’a’)
j = 14(j –>结束)
index_txt = 3(index_txt –>’a’)
index_pat = 11(index_pat –>’*’)
第七比较:-
步骤–(5):i = 4(i –>’b’)
j = 12(j –>’a’)
index_txt = 4(index_txt –>’b’)
index_pat = 11(index_pat –>’*’)
第十八次比较:-
步骤–(5):i = 5(i –>’a’)
j = 12(j –>’a’)
index_txt = 5(index_txt –>’a’)
index_pat = 11(index_pat –>’*’)
第十九次比较:-
步骤–(5):i = 6(i –>’b’)
j = 13(j –>’b’)
index_txt = 5(index_txt –>’a’)
index_pat = 11(index_pat –>’*’)
二十度比较:-
步骤–(5):i = 7(i –>结束)
j = 14(j –>结束)
index_txt = 5(index_txt –>’a’)
index_pat = 11(index_pat –>’*’)
注意:现在,我们将退出运行步骤– 7。
步骤–(7):j已经存在于其结束位置,因此答案是正确的。
下面是上述方法的实现:
C++
// C++ program to implement wildcard
// pattern matching algorithm
#include
using namespace std;
// Function that matches input text
// with given wildcard pattern
bool strmatch(char txt[], char pat[],
int n, int m)
{
// empty pattern can only
// match with empty string.
// Base Case :
if (m == 0)
return (n == 0);
// step-1 :
// initailze markers :
int i = 0, j = 0, index_txt = -1,
index_pat = -1;
while (i < n)
{
// For step - (2, 5)
if (j < m && txt[i] == pat[j])
{
i++;
j++;
}
// For step - (3)
else if (j < m && pat[j] == '?')
{
i++;
j++;
}
// For step - (4)
else if (j < m && pat[j] == '*')
{
index_txt = i;
index_pat = j;
j++;
}
// For step - (5)
else if (index_pat != -1)
{
j = index_pat + 1;
i = index_txt + 1;
index_txt++;
}
// For step - (6)
else
{
return false;
}
}
// For step - (7)
while (j < m && pat[j] == '*')
{
j++;
}
// Final Check
if (j == m)
{
return true;
}
return false;
}
// Driver code
int main()
{
char str[] = "baaabab";
char pattern[] = "*****ba*****ab";
// char pattern[] = "ba*****ab";
// char pattern[] = "ba*ab";
// char pattern[] = "a*ab";
if (strmatch(str, pattern,
strlen(str), strlen(pattern)))
cout << "Yes" << endl;
else
cout << "No" << endl;
char pattern2[] = "a*****ab";
if (strmatch(str, pattern2,
strlen(str), strlen(pattern2)))
cout << "Yes" << endl;
else
cout << "No" << endl;
return 0;
}
Java
// Java program to implement wildcard
// pattern matching algorithm
class GFG {
// Function that matches input text
// with given wildcard pattern
static boolean strmatch(char txt[], char pat[],
int n, int m)
{
// empty pattern can only
// match with empty string.
// Base Case :
if (m == 0)
return (n == 0);
// step-1 :
// initailze markers :
int i = 0, j = 0, index_txt = -1,
index_pat = -1;
while (i < n)
{
// For step - (2, 5)
if (j < m && txt[i] == pat[j])
{
i++;
j++;
}
// For step - (3)
else if (j < m && pat[j] == '?')
{
i++;
j++;
}
// For step - (4)
else if (j < m && pat[j] == '*')
{
index_txt = i;
index_pat = j;
j++;
}
// For step - (5)
else if (index_pat != -1)
{
j = index_pat + 1;
i = index_txt + 1;
index_txt++;
}
// For step - (6)
else
{
return false;
}
}
// For step - (7)
while (j < m && pat[j] == '*')
{
j++;
}
// Final Check
if (j == m)
{
return true;
}
return false;
}
// Driver code
public static void main(String[] args)
{
char str[] = "baaabab".toCharArray();
char pattern[] = "*****ba*****ab".toCharArray();
// char pattern[] = "ba*****ab";
// char pattern[] = "ba*ab";
// char pattern[] = "a*ab";
if (strmatch(str, pattern, str.length,
pattern.length))
System.out.println("Yes");
else
System.out.println("No");
char pattern2[] = "a*****ab".toCharArray();
if (strmatch(str, pattern2, str.length,
pattern2.length))
System.out.println("Yes");
else
System.out.println("No");
}
}
// This code is contributed by Rajput-Ji
Python3
# Python3 program to implement
# wildcard pattern matching
# algorithm
# Function that matches input
# txt with given wildcard pattern
def stringmatch(txt, pat, n, m):
# empty pattern can only
# match with empty sting
# Base case
if (m == 0):
return (n == 0)
# step 1
# initailze markers :
i = 0
j = 0
index_txt = -1
index_pat = -1
while(i < n - 2):
# For step - (2, 5)
if (j < m and txt[i] == pat[j]):
i += 1
j += 1
# For step - (3)
elif(j < m and pat[j] == '?'):
i += 1
j += 1
# For step - (4)
elif(j < m and pat[j] == '*'):
index_txt = i
index_pat = j
j += 1
# For step - (5)
elif(index_pat != -1):
j = index_pat + 1
i = index_txt + 1
index_txt += 1
# For step - (6)
else:
return False
# For step - (7)
while (j < m and pat[j] == '*'):
j += 1
# Final Check
if(j == m):
return True
return False
# Driver code
strr = "baaabab"
pattern = "*****ba*****ab"
# char pattern[] = "ba*****ab"
# char pattern[] = "ba * ab"
# char pattern[] = "a * ab"
if (stringmatch(strr, pattern, len(strr),
len(pattern))):
print("Yes")
else:
print( "No")
pattern2 = "a*****ab";
if (stringmatch(strr, pattern2, len(strr),
len(pattern2))):
print("Yes")
else:
print( "No")
# This code is contributed
# by sahilhelangia
C#
// C# program to implement wildcard
// pattern matching algorithm
using System;
class GFG {
// Function that matches input text
// with given wildcard pattern
static Boolean strmatch(char[] txt, char[] pat,
int n, int m)
{
// empty pattern can only
// match with empty string.
// Base Case :
if (m == 0)
return (n == 0);
// step-1 :
// initailze markers :
int i = 0, j = 0, index_txt = -1,
index_pat = -1;
while (i < n) {
// For step - (2, 5)
if (j < m && txt[i] == pat[j]) {
i++;
j++;
}
// For step - (3)
else if (j < m && pat[j] == '?') {
i++;
j++;
}
// For step - (4)
else if (j < m && pat[j] == '*') {
index_txt = i;
index_pat = j;
j++;
}
// For step - (5)
else if (index_pat != -1) {
j = index_pat + 1;
i = index_txt + 1;
index_txt++;
}
// For step - (6)
else {
return false;
}
}
// For step - (7)
while (j < m && pat[j] == '*') {
j++;
}
// Final Check
if (j == m) {
return true;
}
return false;
}
// Driver code
public static void Main(String[] args)
{
char[] str = "baaabab".ToCharArray();
char[] pattern = "*****ba*****ab".ToCharArray();
// char pattern[] = "ba*****ab";
// char pattern[] = "ba*ab";
// char pattern[] = "a*ab";
if (strmatch(str, pattern, str.Length,
pattern.Length))
Console.WriteLine("Yes");
else
Console.WriteLine("No");
char[] pattern2 = "a*****ab".ToCharArray();
if (strmatch(str, pattern2, str.Length,
pattern2.Length))
Console.WriteLine("Yes");
else
Console.WriteLine("No");
}
}
// This code is contributed by Rajput-Ji
Yes
No
复杂度分析:
- 时间复杂度: O(m + n),其中“ m”和“ n”分别是文本和模式的长度。
- 辅助空间: O(1)。
不使用任何数据结构来存储值