[一起刷leetcode吧] 10.Regular Expression Matching

Regular Expression Matching


题目描述

输入一个字符串s和一个匹配模式p,返回两者是否匹配。匹配规则如下
.可以替代任何字符
*可以重复其之前的字符任何次数(包括0次)
特别的 .*表示任意次数的. 而不是某个确定字符的任意次数


分析

终于刷到一个DP题了,以前做题的时候总是觉得DP最难,现在最想遇到DP题,不想写数据结构。
f[i, j]表示s[:i+1] p[:j+1]是否匹配,状态转移方程如下:

  • s[i] == p[j] or p[j] == '.'
    f[i, j] = f[i-1, j-1]

  • p[j] == '*' and 'a' <= p[j-1] <= 'z'
    f[i, j] |= f[k, j-2] until s[k] != p[j-1] (k = i; k >= 0; k--)

  • p[j] == '*' and p[j-1] == '.'
    f[i, j] |= f[k, j-2] (k = i; k >= 0; k--)

注意边界,我这边为了处理边界,给每个字符串头部添加了一个#


代码

class Solution {
public:
	bool isMatch(string s, string p) {
		int len_s = s.size() + 1, len_p = p.size() + 1;
		s.insert(0, "#");
		p.insert(0, "#");
		bool f[21][31] = { false };
		f[0][0] = true;
		for (int i = 0; i < len_s; i++) {
			for (int j = 0; j < len_p; j++) {
				if (i + j == 0)
					continue;
				
				if (i == 0)
				{
					if (p[j] >= 'a' && p[j] <= 'z' or p[j] == '.')
						f[i][j] = false;
					if (j > 1 && p[j] == '*')
						f[i][j] = f[i][j - 2];
					continue;
				}
				
				if (j == 0)
				{
					f[i][j] = false;
					continue;
				}

				if (p[j] >= 'a' && p[j] <= 'z')
				{
					if (s[i] == p[j])
						f[i][j] = f[i - 1][j - 1];
					else
						f[i][j] = false;
				}
				if (p[j] == '.')
					f[i][j] = f[i - 1][j - 1];
				if (j > 1 && p[j] == '*' && p[j - 1] >= 'a' && p[j - 1] <= 'z')
				{
					for (int k = i; k >= 0; k--)
					{
						if (f[k][j - 2])
						{
							f[i][j] = true;
							break;
						}
						if (s[k] != p[j - 1])
							break;
					}
				}
				if (j > 1 && p[j] == '*' && p[j - 1] == '.')
				{
					for (int k = i; k >= 0; k--)
					{
						if (f[k][j - 2])
						{
							f[i][j] = true;
							break;
						}
					}
				}
			}
		}
		return f[len_s - 1][len_p - 1];
	}
};

思考

总感觉这个匹配规则和标准的正则匹配有点不同,但有人直接用正则匹配的函数好像也能AC,挺神奇的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值