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];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值