LeetCode: Wildcard Matching (通配符匹配)
2013-04-30 06:00
183 查看
Implement wildcard pattern matching with support for
首先要弄清楚什么是通配符匹配。需要注意通配符在匹配每一个字符的时候,不需要管这个字符之前的匹配结果。
这道题可以用回溯法解决。需要回溯的地方是在p中遇到一个'*'的时候,我们不能确定需要s中的几个字符去匹配这个'*',所以就进行尝试。首先从一个都不用去匹配,如果不成功就用s中从当前字符去匹配,再不成功就用s中的下一个字符去匹配,一直这样下去,直到成功匹配或者匹配了s中的所有剩余字符。
回溯法的代码:
由于通配符匹配的时候,可以看做分段匹配,将p根据‘*’分成不同的部分,把这些部分分别放在s中做字符串匹配,只要能匹配并且各个部分不重叠,那么最终就是匹配的。比如p = abc****d?f*ghi,p可分为三段,abc,
def, ghi。将这三段分别与s进行匹配。
需要注意的地方是第一段和最后一段的匹配。如果第一段的第一个字符不是‘*’,则第一段就需要从第一个字符开始正向进行匹配。如果最后一段的最后一个字符不是‘*’,则最后一段需要从最后一个字符开始反向匹配。
迭代实现的代码很繁琐。
'?'and
'*'.
'?' Matches any single character. '*' Matches any sequence of characters (including the empty sequence). The matching should cover the entire input string (not partial). The function prototype should be: bool isMatch(const char *s, const char *p) Some examples: isMatch("aa","a") ? false isMatch("aa","aa") ? true isMatch("aaa","aa") ? false isMatch("aa", "*") ? true isMatch("aa", "a*") ? true isMatch("ab", "?*") ? true isMatch("aab", "c*a*b") ? false
首先要弄清楚什么是通配符匹配。需要注意通配符在匹配每一个字符的时候,不需要管这个字符之前的匹配结果。
这道题可以用回溯法解决。需要回溯的地方是在p中遇到一个'*'的时候,我们不能确定需要s中的几个字符去匹配这个'*',所以就进行尝试。首先从一个都不用去匹配,如果不成功就用s中从当前字符去匹配,再不成功就用s中的下一个字符去匹配,一直这样下去,直到成功匹配或者匹配了s中的所有剩余字符。
回溯法的代码:
public boolean isMatch(String s, String p) { // Start typing your Java solution below // DO NOT write main() function if (p.length() == 0) { return s.length() == 0; } if (p.charAt(0) != '*') { if (s.length() != 0 && (p.charAt(0) == s.charAt(0) || p.charAt(0) == '?')) { return isMatch(s.substring(1), p.substring(1)); } else { return false; } } while (s.length() != 0) { while (p.length() > 1 && p.charAt(1) == '*') { p = p.substring(1); } if (isMatch(s, p.substring(1))) { return true; } s = s.substring(1); } return isMatch(s, p.substring(1)); }这个代码无法通过LeetCode的大集合。尝试使用迭代去解决。
由于通配符匹配的时候,可以看做分段匹配,将p根据‘*’分成不同的部分,把这些部分分别放在s中做字符串匹配,只要能匹配并且各个部分不重叠,那么最终就是匹配的。比如p = abc****d?f*ghi,p可分为三段,abc,
def, ghi。将这三段分别与s进行匹配。
需要注意的地方是第一段和最后一段的匹配。如果第一段的第一个字符不是‘*’,则第一段就需要从第一个字符开始正向进行匹配。如果最后一段的最后一个字符不是‘*’,则最后一段需要从最后一个字符开始反向匹配。
迭代实现的代码很繁琐。
public int stringMatch(String s, String p) { int sLen = s.length(); int pLen = p.length(); int i = 0; int j = 0; for (; i < sLen && j < pLen; i++, j++) { if (s.charAt(i) != p.charAt(j) && p.charAt(j) != '?') { i = i - j; j = -1; } } if (j == pLen) { return i - j; } else { return -1; } } public boolean isMatch(String s, String p) { // Start typing your Java solution below // DO NOT write main() function String matchStr = null; int first = p.indexOf('*'); if (first == -1) { // no '*' in the pattern // s and p must exactly match return stringMatch(s, p) == 0 && s.length() == p.length(); } if (first > 0) { // p does not begin with '*' // check beginning part of p (before the first '*') // forward match from the beginning characters of s and p matchStr = p.substring(0, first); int i = 0; int j = 0; for (; i < s.length() && j < matchStr.length(); i++, j++) { if (s.charAt(i) != matchStr.charAt(j) && matchStr.charAt(j) != '?') { return false; } } if (j < matchStr.length()) { return false; } // discard matched part in s after matching s = s.substring(matchStr.length()); } int last = p.lastIndexOf('*'); if (last < p.length() - 1) { // p does not end with '*' // check last part of p (after the very last '*') // backward match from the last characters of s and p matchStr = p.substring(last + 1); int i = s.length() - 1; int j = matchStr.length() - 1; for (; i >= 0 && j >= 0; i--, j--) { if (s.charAt(i) != matchStr.charAt(j) && matchStr.charAt(j) != '?') { return false; } } if (j >= 0) { return false; } // discard matched part in s after matching s = s.substring(0, s.length() - matchStr.length()); } // discard matched part in p p = p.substring(first, last + 1); // discard consecutive '*' from the front of p while (p.length() != 0 && p.charAt(0) == '*') { p = p.substring(1); } // discard consecutive '*' from the tail of p while (p.length() != 0 && p.charAt(p.length() - 1) == '*') { p = p.substring(0, p.length() - 1); } // iteratively match the rest part of p while (p.length() != 0) { int star = p.indexOf('*'); if (star != -1) { matchStr = p.substring(0, star); } else { matchStr = p; } int match = stringMatch(s, matchStr); if (match == -1) { return false; } p = p.substring(matchStr.length()); while (p.length() != 0 && p.charAt(0) == '*') { p = p.substring(1); } s = s.substring(match + matchStr.length()); } return true; }
相关文章推荐
- leetcode Wildcard Matching ,Regular Expression Matching (正则表达式匹配和通配符匹配)
- leetCode 44.Wildcard Matching (通配符匹配) 解题思路和方法
- leetcode-44 Wildcard Matching 通配符匹配
- LeetCode-Wildcard Matching-通配符匹配-DP
- [LeetCode]Wildcard Matching 通配符匹配(贪心)
- [LeetCode][Facebook面试题] 通配符匹配和正则表达式匹配,题 Wildcard Matching
- [LeetCode] Wildcard Matching 通配符匹配
- [LeetCode]Wildcard Matching 通配符匹配(贪心)
- LeetCode 44. Wildcard Matching(通配符匹配)
- (Java) LeetCode 44. Wildcard Matching —— 通配符匹配
- [leetcode] Wildcard Matching 通配符匹配
- [Lintcode]Wildcard Matching 通配符匹配
- Wildcard Matching 通配符匹配
- Wildcard Matching[leetcode]直接匹配和DP
- LeetCode------44. Wildcard Matching(?*匹配)
- [LeetCode] 44. Wildcard Matching 外卡匹配
- 44. Wildcard Matching(通配符匹配)
- LeetCode 44. Wildcard Matching(模糊匹配)
- 通配符匹配字符串 Wildcard Matching
- Leet Code 44 Wildcard Matching - 通配符匹配 - Java