LintCode154:正则表达式匹配(Java)

具体题目说明:https://www.lintcode.com/problem/regular-expression-matching/description
觉得这个比较有意思,就研究了下,算是温习了下DP,这是个普通实现,对一些关键步骤做了理解和说明

Java实现

/**
 * 实现支持'.'和'*'的正则表达式匹配
 * .匹配任意一个字母 *匹配零个或者多个前面的元素
 * @param s 待匹配的字符串
 * @param p 表达式
 * @return 是否匹配
 */
public static boolean isMatch(String s, String p) {

  int s_length = s.length();
  int p_length = p.length();
  // record表示s中的前i个字符与p中的前j个字符匹配情况
  boolean[][] record = new boolean[s_length + 1][p_length + 1];

  // 然后从s第一个字符开始匹配,都能匹配上那么就算成功
  for (int i = 0; i <= s_length; i++) {
    for (int j = 0; j <= p_length; j++) {
      // 初始化,可以理解为""和""匹配
      if (i == 0 && j == 0) {
        record[i][j] = true;
        continue;
      }
      // 表示任意除""外的字符和""表达式均不匹配
      // 这里可能有一个疑问,为什么没有i == 0的情况,我们举个例子s为"",p为a*,他们就是匹配关系
      if (j == 0) {
        record[i][j] = false;
        continue;
      }

      // 这里即用动态规划,从前后关系上来逐步推断匹配关系,从初始状态一步步计算后面每步结果
      // 情况1: 当i处字符和j处字符相同或者j处字符为'.'时,i及之前的字符串和j及之前的字符串是否匹配
      // 只取决于i-1和j-1处匹配状况
      if (i > 0 && (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '.')) {
        record[i][j] = record[i - 1][j - 1];
      } else if (p.charAt(j - 1) == '*' && j > 1) {
        // 情况2: 当j处字符为'*'时(注意j>1),这里就分'*'匹配零个和多个,任意一个匹配上均表示匹配上
        // 情况2-1: 当'*'之前一个(j-2)字符和i处字符相同或者'*'之前一个(j-2)字符为'.'时,
        // 这时'*'至少匹配一个字符,那么消掉i处一个字符,所以i,j处的匹配关系由i-1,j即可确定
        if (i > 0 && (s.charAt(i - 1) == p.charAt(j - 2) || p.charAt(j - 2) == '.')) {
          record[i][j] = record[i - 1][j];
        }
        // 情况2-2: 匹配零个,注意使用|(或)的关系
        // 理解""和a*匹配这个例子很重要,因为*匹配零个或者多个多个前面的元素,所以当j为*时,匹配零个'a',
        // 故可消掉*和'a',那么只需看""和'a'之前的字符是否匹配即可,也就是j-2
        record[i][j] |= record[i][j - 2];
      }
    }
  }
  return record[s_length][p_length];
}
发布了71 篇原创文章 · 获赞 2 · 访问量 6027
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 1024 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览