📌  相关文章
📜  检查给定字符串是否存在给定模式

📅  最后修改于: 2021-09-06 06:38:56             🧑  作者: Mango

给定两个字符串text和长度分别为MN 的模式,任务是检查模式是否文本匹配。如果发现是真的,则打印“是” 。否则,打印“否”

注意:模式可以包含字符“*”“•”

  • 当前字符之前“*”匹配零个或多个字符权
  • ‘•’匹配任何信号字符。

例子:

朴素的方法:解决这个问题的最简单的方法是使用递归遍历两个字符串的字符。如果当前字符是‘.’ , 将当前字符替换为任何字符并重复剩余模式文本字符串。否则,如果当前字符是‘*’ ,则重复剩余的文本并检查它是否与模式的其余部分匹配。如果发现是真的,则打印“是” 。否则,打印“否”

时间复杂度: O((M + N) * 2 (M + N / 2 ) )
辅助空间: O((M + N) * 2 (M + N / 2 ) )

高效方法:上述方法可以使用动态规划进行优化。以下是递推关系:

  • 初始化一个二维数组dp[M + 1][N + 1] ,其中dp[i][j]检查子串{ text[0], …, text[i] }是否与子串{ pattern[ 0], … pattern[j] }或不。
  • 遍历这两个字符串的字符,并填写基于以下递推关系的DP [] []数组:
    • 如果text[i]pattern[j]相同,则填充dp[i + 1][j + 1] = dp[i][j]
    • 如果模式 [j]‘.’然后填充dp[i + 1][j + 1] = dp[i][j]。
    • 如果pattern[j]‘*’,则检查以下条件:
      • 如果text[i]不等于pattern[j – 1]并且pattern[j – 1]不等于‘.’ ,然后填充dp[i + 1][j + 1] = dp[i + 1][j – 1]
      • 否则填充dp[i + 1][j + 1] = (dp[i + 1][j] || dp[i][j + 1] || dp[i + 1][j – 1]) .
  • 最后,打印dp[M][N] 的值

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to check if the pattern
// consisting of '*', '.' and lowercase
// characters matches the text or not
int isMatch(string text, string pattern)
{
 
  // Base Case
  if (text == "" or pattern == "")
    return false;
 
  // Stores length of text
  int N = text.size();
 
  // Stores length of pattern
  int M = pattern.size();
 
  // dp[i][j]: Check if { text[0], .. text[i] }
  // matches {pattern[0], ... pattern[j]} or not
  vector> dp(N + 1, vector(M + 1, false));
 
  // Base Case
  dp[0][0] = true;
 
  // Iterate over the characters
  // of the string pattern
  for (int i = 0; i < M; i++)
  {
    if (pattern[i] == '*'
        && dp[0][i - 1]) {
 
      // Update dp[0][i + 1]
      dp[0][i + 1] = true;
    }
  }
 
  // Iterate over the characters
  // of both the strings
  for (int i = 0; i < N; i++) {
 
    for (int j = 0; j < M; j++) {
 
      // If current character
      // in the pattern is '.'
      if (pattern[j] == '.') {
 
        // Update dp[i + 1][j + 1]
        dp[i + 1][j + 1] = dp[i][j];
      }
 
      // If current character in
      // both the strings are equal
      if (pattern[j]
          == text[i]) {
 
        // Update dp[i + 1][j + 1]
        dp[i + 1][j + 1] = dp[i][j];
      }
 
      // If current character
      // in the pattern is '*'
      if (pattern[j] == '*') {
 
        if (pattern[j - 1] != text[i]
            && pattern[j - 1] != '.') {
 
          // Update dp[i + 1][j + 1]
          dp[i + 1][j + 1] = dp[i + 1][j - 1];
        }
 
        else {
 
          // Update dp[i+1][j+1]
          dp[i + 1][j + 1] = (dp[i + 1][j]
                              or dp[i][j + 1]
                              or dp[i + 1][j - 1]);
        }
      }
    }
  }
 
  // Return dp[M][N]
  return dp[N][M];
}
 
// Driver Code
int main()
{
  string text = "geeksforgeeks";
  string pattern = "ge*ksforgeeks";
 
  if (isMatch(text, pattern))
    cout<<"Yes";
  else
    cout<<"No";
}
 
// This code is contributed by mohiy kumar 29.


Java
// Java program for the above approach
 
import java.io.*;
 
class GFG {
 
    // Function to check if the pattern
    // consisting of '*', '.' and lowercase
    // characters matches the text or not
    static boolean isMatch(String text,
                           String pattern)
    {
        // Base Case
        if (text == null || pattern == null) {
            return false;
        }
 
        // Stores length of text
        int N = text.length();
 
        // Stores length of pattern
        int M = pattern.length();
 
        // dp[i][j]: Check if { text[0], .. text[i] }
        // matches {pattern[0], ... pattern[j]} or not
        boolean[][] dp = new boolean[N + 1][M + 1];
 
        // Base Case
        dp[0][0] = true;
 
        // Iterate over the characters
        // of the string pattern
        for (int i = 0; i < M; i++) {
            if (pattern.charAt(i) == '*'
                && dp[0][i - 1]) {
 
                // Update dp[0][i + 1]
                dp[0][i + 1] = true;
            }
        }
 
        // Iterate over the characters
        // of both the strings
        for (int i = 0; i < N; i++) {
 
            for (int j = 0; j < M; j++) {
 
                // If current character
                // in the pattern is '.'
                if (pattern.charAt(j) == '.') {
 
                    // Update dp[i + 1][j + 1]
                    dp[i + 1][j + 1] = dp[i][j];
                }
 
                // If current character in
                // both the strings are equal
                if (pattern.charAt(j)
                    == text.charAt(i)) {
 
                    // Update dp[i + 1][j + 1]
                    dp[i + 1][j + 1] = dp[i][j];
                }
 
                // If current character
                // in the pattern is '*'
                if (pattern.charAt(j) == '*') {
 
                    if (pattern.charAt(j - 1) != text.charAt(i)
                        && pattern.charAt(j - 1) != '.') {
 
                        // Update dp[i + 1][j + 1]
                        dp[i + 1][j + 1] = dp[i + 1][j - 1];
                    }
 
                    else {
 
                        // Update dp[i+1][j+1]
                        dp[i + 1][j + 1] = (dp[i + 1][j]
                                            || dp[i][j + 1]
                                            || dp[i + 1][j - 1]);
                    }
                }
            }
        }
 
        // Return dp[M][N]
        return dp[N][M];
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        String text = "geeksforgeeks";
        String pattern = "ge*ksforgeeks";
 
        if (isMatch(text, pattern)) {
 
            System.out.println("Yes");
        }
        else {
 
            System.out.println("No");
        }
    }
}


Python3
# Python3 program for the above approach
import numpy as np
 
# Function to check if the pattern
# consisting of '*', '.' and lowercase
# characters matches the text or not
def isMatch(text, pattern):
     
  # Base Case
  if (text == "" or pattern == ""):
    return False
 
  # Stores length of text
  N = len(text)
 
  # Stores length of pattern
  M = len(pattern)
 
  # dp[i][j]: Check if { text[0], .. text[i] }
  # matches {pattern[0], ... pattern[j]} or not
  dp = np.zeros((N + 1, M + 1))
 
  # Base Case
  dp[0][0] = True
 
  # Iterate over the characters
  # of the string pattern
  for i in range(M):
    if (pattern[i] == '*' and dp[0][i - 1]):
 
      # Update dp[0][i + 1]
      dp[0][i + 1] = True
 
  # Iterate over the characters
  # of both the strings
  for i in range(N):
    for j in range(M):
 
      # If current character
      # in the pattern is '.'
      if (pattern[j] == '.'):
 
        # Update dp[i + 1][j + 1]
        dp[i + 1][j + 1] = dp[i][j]
 
      # If current character in
      # both the strings are equal
      if (pattern[j] == text[i]):
 
        # Update dp[i + 1][j + 1]
        dp[i + 1][j + 1] = dp[i][j]
 
      # If current character
      # in the pattern is '*'
      if (pattern[j] == '*'):
        if (pattern[j - 1] != text[i] and
            pattern[j - 1] != '.'):
 
          # Update dp[i + 1][j + 1]
          dp[i + 1][j + 1] = dp[i + 1][j - 1]
         
        else:
 
          # Update dp[i+1][j+1]
          dp[i + 1][j + 1] = (dp[i + 1][j] or
                              dp[i][j + 1] or
                              dp[i + 1][j - 1])
 
  # Return dp[M][N]
  return dp[N][M]
 
# Driver Code
if __name__ == "__main__" :
 
  text = "geeksforgeeks"
  pattern = "ge*ksforgeeks"
   
  if (isMatch(text, pattern)):
    print("Yes")
  else:
    print("No")
 
# This code is contributed by AnkThon


C#
// C# program for the above approach
using System;
 
class GFG{
 
// Function to check if the pattern
// consisting of '*', '.' and lowercase
// characters matches the text or not
static bool isMatch(string text, string pattern)
{
     
    // Base Case
    if (text == null || pattern == null)
    {
        return false;
    }
 
    // Stores length of text
    int N = text.Length;
 
    // Stores length of pattern
    int M = pattern.Length;
 
    // dp[i][j]: Check if { text[0], .. text[i] }
    // matches {pattern[0], ... pattern[j]} or not
    bool[,] dp = new bool[N + 1, M + 1];
 
    // Base Case
    dp[0, 0] = true;
 
    // Iterate over the characters
    // of the string pattern
    for(int i = 0; i < M; i++)
    {
        if (pattern[i] == '*' && dp[0, i - 1])
        {
             
            // Update dp[0][i + 1]
            dp[0, i + 1] = true;
        }
    }
 
    // Iterate over the characters
    // of both the strings
    for(int i = 0; i < N; i++)
    {
        for(int j = 0; j < M; j++)
        {
             
            // If current character
            // in the pattern is '.'
            if (pattern[j] == '.')
            {
                 
                // Update dp[i + 1][j + 1]
                dp[i + 1, j + 1] = dp[i, j];
            }
 
            // If current character in
            // both the strings are equal
            if (pattern[j] == text[i])
            {
                 
                // Update dp[i + 1][j + 1]
                dp[i + 1, j + 1] = dp[i, j];
            }
 
            // If current character
            // in the pattern is '*'
            if (pattern[j] == '*')
            {
                if (pattern[j - 1] != text[i] &&
                    pattern[j - 1] != '.')
                {
                     
                    // Update dp[i + 1][j + 1]
                    dp[i + 1, j + 1] = dp[i + 1, j - 1];
                }
 
                else
                {
                     
                    // Update dp[i+1][j+1]
                    dp[i + 1, j + 1] = (dp[i + 1, j] ||
                                        dp[i, j + 1] ||
                                        dp[i + 1, j - 1]);
                }
            }
        }
    }
 
    // Return dp[M][N]
    return dp[N, M];
}
 
// Driver Code
public static void Main()
{
    string text = "geeksforgeeks";
    string pattern = "ge*ksforgeeks";
 
    if (isMatch(text, pattern))
    {
        Console.WriteLine("Yes");
    }
    else
    {
        Console.WriteLine("No");
    }
}
}
 
// This code is contributed by ukasp


输出:
Yes

时间复杂度: O(M * N)
辅助空间: O(M * N)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live