zoukankan      html  css  js  c++  java
  • [LeetCode] 10. Regular Expression Matching(正则匹配)

    Description

    Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*' where:
    给定一输入字符串 s 和匹配规则 p,实现一个正则表达式引擎,要求能支持 '.''*' 的匹配,其中:

    • '.' Matches any single character.
      '.' 匹配任意单个字符。​​​​
    • '*' Matches zero or more of the preceding element.
      '*' 将其前面一个元素匹配 0 或多次。

    The matching should cover the entire input string (not partial).
    匹配应该针对整个字符串进行(非部分)。

    Examples

    Example 1

    Input: s = "aa", p = "a"
    Output: false
    Explanation: "a" does not match the entire string "aa".
    

    Example 2

    Input: s = "aa", p = "a*"
    Output: true
    Explanation: '*' means zero or more of the preceding element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".
    

    Example 3

    Input: s = "ab", p = ".*"
    Output: true
    Explanation: ".*" means "zero or more (*) of any character (.)".
    

    Example 4

    Input: s = "aab", p = "c*a*b"
    Output: true
    Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore, it matches "aab".
    

    Example 5

    Input: s = "mississippi", p = "mis*is*p*."
    Output: false
    

    Constraints

    • 0 <= s.length <= 20
    • 0 <= p.length <= 30
    • s contains only lowercase English letters.
    • p contains only lowercase English letters, '.', and '*'.
    • It is guaranteed for each appearance of the character '*', there will be a previous valid character to match.

    Solution

    这题的做法有点像最长公共子序列。定义 dp(i, j) 表示 s[0, i]p[0, j] 的匹配结果(字符串下标从 1 开始):

    1. dp(0, 0) = true(空串匹配空串);

    2. s[i] == p[j],显然,dp(i, j) = dp(i - 1, j - 1)

    3. p[j] == '.',自然也能匹配,dp(i, j) = dp(i - 1, j - 1)

    4. p[j] == '*',则又有以下几种情况:

      1. s[i] != p[j]:则此时不能匹配任何字符,dp(i, j) = dp(i, j - 2)

      2. s[i] == p[j]p[j - 1] == '.':此时以下三种情况都可以匹配

        1. dp(i, j) = dp(i - 1, j)(匹配多个字符)

        2. dp(i, j) = dp(i, j - 1)(匹配一个字符)

        3. dp(i, j) = dp(i, j - 2)(不匹配任何字符)

    代码如下

    class Solution {
        fun isMatch(s: String, p: String): Boolean {
            val dp = Array(s.length + 1) { BooleanArray(p.length + 1) }
            dp[0][0] = true
            for (i in p.indices) {
                if (p[i] == '*' && dp[0][i - 1]) {
                    dp[0][i + 1] = true
                }
            }
    
            for (i in s.indices) {
                for (j in p.indices) {
                    doMatching(s, i, p, j, dp)
                }
            }
            return dp.last().last()
        }
    
        private fun doMatching(
            s: String,
            i: Int,
            p: String,
            j: Int,
            dp: Array<BooleanArray>
        ) {
            if (p[j] == '.') {
                dp[i + 1][j + 1] = dp[i][j]
            }
            if (p[j] == s[i]) {
                dp[i + 1][j + 1] = dp[i][j]
            }
            if (p[j] == '*') {
                if (p[j - 1] != s[i] && p[j - 1] != '.') {
                    dp[i + 1][j + 1] = dp[i + 1][j - 1]
                } else {
                    dp[i + 1][j + 1] = (dp[i + 1][j] || dp[i][j + 1] || dp[i + 1][j - 1])
                }
            }
        }
    }
    
  • 相关阅读:
    个人管理:提高你的搜商
    敏捷个人:提供更多文档下载,并转载一篇敏捷个人读书笔记
    个人管理: 激励你的一句话
    敏捷个人 从Scrum实践来思考如何导入价值观
    信息系统开发平台OpenExpressApp 如何解决ComboBox.TextProperty绑定带来问题的来龙去脉
    敏捷个人 敏捷个人价值观,欢迎提出你的意见和你的价值观
    使用VS2010的CodedUI来做自己的自动化测试框架
    .Net4下的MEF(Managed Extensibility Framework) 架构简介
    IronRuby - 快速在半小时学习Ruby基础知识
    敏捷个人 项目网站文档页签增加blog链接
  • 原文地址:https://www.cnblogs.com/zhongju/p/14197001.html
Copyright © 2011-2022 走看看