[Leetcode P10]Regular Expression Matching 正则匹配
来源:互联网 发布:淘宝跳蚤街与闲鱼 编辑:程序博客网 时间:2024/06/12 01:31
总共用了两种解法,一种是我自己递归求解的,效率很低,边界条件很难理清楚,代码很长,第二种是DP解法,把递归的子问题的解存到一个数组里,代码很短。
1. 递归解法
主要想法是根据当前的正则表达式,来决定接下去如何匹配,我们可以用两个字符串的子串去匹配,麻烦的是,可能相同的子字符串被求解了很多遍,特别是.*对应的字符串需要循环求解。写完这个解法以后,我很自然地就知道可以用DP递归求解了,不过边际条件比较难确定,我们可以
struct match{ bool isMatch; char c; int pos;};class Solution {public: vector<match> matchArray; string reg; bool Match(string s, int current){ for (int i = 0; i < s.length(); ++i) { if (current >= matchArray.size()) { return false; } match m = matchArray[current]; if (m.c == '.' && m.isMatch == true) { if (current == matchArray.size() - 1) { return true; } else { while(matchArray[current].isMatch){ current++; if (current >= matchArray.size()) { return true; } } char c = matchArray[current].c; bool isMatch = matchArray[current].isMatch; for (int j = i; j < s.length(); ++j) { if (Match(s.substr(j), current)) { return true; } } return false; } } else if (m.c == '.') { current++; } else if (m.isMatch == true) { if (Match(s.substr(i), current + 1)) { return true; } else if (s[i] != m.c) { return false; } while(s[i] == m.c){ i++; if (Match(s.substr(i), current + 1)) { return true; } } return false; } else if (m.c != s[i]) { return false; } else{ current++; } } for (int i = current; i < matchArray.size(); ++i) { if (matchArray[i].isMatch == false) { return false; } } return true; } bool isMatch(string s, string p) { reg = p; if (p.length() == 0 && s.length() == 0) { return true; } else if (p.length() == 0 /*|| s.length() == 0*/) { return false; } for (int i = 0; i < p.length(); ++i) { match m; m.pos = i; m.c = p[i]; if (i + 1 < p.length() && p[i+1] == '*') { m.isMatch = true; i++; } else{ m.isMatch = false; } matchArray.push_back(m); } return Match(s, 0); }};
- DP解法
我们可以顺其自然地记录子问题的解,代码里注释比较全。
// 既然可以递归求解,那应该可以记录子节点的情况,做DP// 我们选择的是p的长度为j的子串是否匹配s的长度为i的子串class Solution {public: bool dp[100][100]; bool isMatch(string s, string p) { dp[0][0]=true; for (int i = 1; i <= s.length(); ++i) { dp[i][0]=false; } int len1 = s.length(); int len2 = p.length(); for (int i = 0; i <= len1; ++i) { // 注意i=0对应的是s是空串的情况 for (int j = 1; j <= len2; ++j) { // 同样的j=0对应的是p=0的情况,而且我们已经初始化过了 // i,j对应的是字符串的 if (p[j-1] == '*') { if (p[j-2]=='.' || (i>0&&p[j-2]==s[i-1])) { // p_j-2可以匹配s的结尾,那么只需要匹配情况和长度为i-1的s一样就可以了 // 主要是x*可以匹配0/1个: // 1 如果p可以匹配s,则px*一定匹配sx // 2 如果p不可以匹配s,则: // 2.1 如果希望px*匹配sx,那么说明x*匹配的不是单一的x: // 2.1.1 x*匹配的是空,则p匹配sx也就是dp[i][j-2]=true // 2.1.2 x*匹配的是xxxxx,做了k次匹配,则px*一定也可以匹配sxxxx(k-1个x) // ,也就是dp[i-1][j]=true(还要求i>0) // 2.2 匹配的情况只有以上两种,不匹配的话取反就可以了,而dp[i][j-2]已经做了相应的记录,直接用就好 // 而且因为*不会出现在p开头,所以j>=2 // 这里可能会出现一些误解,只要想清楚p[j-2]对应的长度是j-1,dp[i][j-2]对应的长度是j-2就可以 dp[i][j]=(i>0&&dp[i-1][j])||dp[i][j-2]; } else{ // 如果不能匹配结尾,说明x*毫无作用,它做了0次匹配,对应的是2.1.1的情况 dp[i][j]=dp[i][j-2]; } } else if (i>0 && (p[j-1]=='.' || p[j-1]==s[i-1])) { // 这里如果p可以匹配s,那么p.可以匹配sx,如果p不可以匹配s,那么p.也不可以匹配sx // px和sx是同理的 dp[i][j]=dp[i-1][j-1]; } else{ // 其他情况下,也就是说,pa不匹配sb,那么我们暂时让它等于false // 这个条件,我在yy的时候,一直在想p有.*的情况,好像理不清楚的样子 // 其实很简单,p'.*a和sb一样是不匹配的,p'.*其实在第一步讨论过了 dp[i][j]=false; } } } return dp[len1][len2]; }};
阅读全文
0 0
- [Leetcode P10]Regular Expression Matching 正则匹配
- [LeetCode]—Regular Expression Matching 正则匹配
- LeetCode 10 Regular Expression Matching 正则匹配
- 正则表达式匹配-leetcode Regular Expression Matching
- regular expression matching 正则匹配
- LeetCode 面试题 Regular expression matching(正则匹配)
- 判断正则表达式是否匹配 Regular Expression Matching @LeetCode
- LeetCode OJ 之 Regular Expression Matching (正则表达式匹配)
- LeetCode 10 Regular Expression Matching (正则表达式匹配)
- leetcode系列(34)Regular Expression Matching 正则表达式匹配
- Leetcode #10 Regular Expression Matching 正则表达式匹配 解题小节
- LeetCode 10. Regular Expression Matching(正则表达式匹配)
- leetcode(10) - Regular Expression Matching 正则表达式匹配
- leetcode 10 Regular Expression Matching(简单正则表达式匹配)
- 通配符匹配 & 正则表达式匹配【leetcode Wildcard Matching & Regular Expression Matching】
- leetcode Wildcard Matching ,Regular Expression Matching (正则表达式匹配和通配符匹配)
- Regular Expression Matching 正则匹配问题
- Regular Expression Matching 正则表达式匹配
- 多线程之初理解
- Linux和Windonws下静态库与动态库(动态库篇)
- HDU3264 Open-air shopping malls【几何】
- Recycleview的各种炫酷应用
- 【转】【Oracle】oracle登录验证的三种方式(详解)
- [Leetcode P10]Regular Expression Matching 正则匹配
- 在linux下安装mysql
- STL——迭代器
- chrome调试js高能技巧
- Tms320c6678——多核导航模块(Multicore Navigator)
- Apache 开启SSI 支持 html inculde
- STS 无法启动
- design点击波纹效果
- Signal Interference -(hdu5130)