[LeetCode]44. Wildcard Matching 深入浅出讲解和代码示例
来源:互联网 发布:linux mysql开机自启 编辑:程序博客网 时间:2024/05/29 17:19
1、汇总概要
本题是模式匹配问题,解题思路涵盖了递归、以及匹配算法的知识点
2、题目
Implement wildcard pattern matching with support for '?'
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") ? falseisMatch("aa","aa") ? trueisMatch("aaa","aa") ? falseisMatch("aa", "*") ? trueisMatch("aa", "a*") ? trueisMatch("ab", "?*") ? trueisMatch("aab", "c*a*b") ? false
3、审题
该题是模式匹配问题。
4、解题思路
1、原串(s)和模式串(p)匹配规则考虑时,涉及到三种基本情况,以及其任意组合:
1) 模式串当前是字符时(p[j]是char):相等则继续比较下一个,不相等则返回不匹配(false)
2) p[j] == ‘?’时:当做相等,继续比较下一个;
3) p[j] == '*'时:跳过*,s中当前位置查看是否有与p[j+1]匹配的元素,这种情况较复杂。
以s='abcdefga', p='ab?*g*'为例,示意图讲解如下:
Step1:初始i=0, j=0,顺序比较s[i]和p[j], 相同时指针指向下一个,继续比较;不等时,返回false;
Step2:p[j] == '?'时,任意字符与其匹配,指针指向下一个继续比较;
Step3:p[j] == '*'时(j=3),跳过*,比较*的下一个字符p[4](即'g'),从s[3]开始,查找后面的字符是否有'g'(p[6]),
1)若能找到, 则从其位置开始,继续循环执行Step1~Step3;
2)若找不到,返回false;
以上是基本思路,确定比较规则后,代码中循环遍历即可。
2、还有一种较复杂的情况需考虑,在Step3中比较*后面的字符时,如果匹配到多个,应该以哪个为准?这种情况容易被忽略。
举例:
1)当s='abab', p='*abab'时:
'*'后面的'a'在s中多个位置都可以找到(i=0,i=2)那么应该以哪个位置为准呢:
以i=0为准(即从i=0的下一个位置开始,继续下一个比较),结果是true;
以i=2为准,结果是false;
结论:本例中应该以第一次匹配到的位置为准,即i=0;
2)s='abab', p='*ab'时,以1)例中同样的方式分析,应该以最后一次匹配到的位置为准,即i=2;
所以,这里有个动态规划的思路,在处理时,并不能确定应该是以第一次匹配到的位置为准,还是最后一次,或者是中间的某一次匹配到的位置。
妥善的处理方法是,遍历所有s串中可以匹配到*下一个字符的位置,止到结果是true。
[当存在多个*时,仍然用这种思路处理]
动态规划的常用实现方法是递归函数(实现代码见下)。
5、代码示例 - Java
public class WildcardMatching {public boolean subMatch(String s, String p,int iStart,int jStart) throws InterruptedException{int i = iStart;int j = jStart;int lens = s.length();int lenp = p.length();System.out.println("\n\nrecursion ====== "+lens+" "+lenp);boolean res = false;while(j<lenp && i<lens){System.out.println("\ngo loop--i,j: "+i+" "+j);//Thread.currentThread().sleep(1000);if(p.charAt(j)=='*'){/*get its next char * if next is *, skip => j++, and break;(no need to recursion) * if next is ? => i++(start index skep 1),j++; */if(j<lenp-1){//have next onej++;if(p.charAt(j)=='*'){//next is *j++;continue; //go to loop again}else if(p.charAt(j)=='?'){ //next is ?i++;j++;if(i>=lens-1){//? match the last one in swhile(j<lenp && p.charAt(j)=='*'){//one/multiple * after ?j++;}if(j>=lenp){res = true;return res;}}continue; //go to loop again}else{//go to recursion branchwhile(i<lens){while(i<lens && p.charAt(j)!=s.charAt(i)){if(p.charAt(j)=='?'){break;}i++;}/*if exist multiple i met,need to save all * 1)s=abab,p=*abab,i should choose 0 * 2)s=abab,p=*ab,i should choose 2 */res = subMatch(s,p,i,j);i++;if(res == true){return res;}//else, do recursion}continue;}}else{ //j>= lenp; one/multiple * in the tail of pres = true;return res;}} //end if(*)if(i<lens-1 && j==lenp-1){ //p get the endif(p.charAt(j)=='*'){res = true;}else{res = false;}return res;}else if(i==lens-1 && j<lenp-1){//s get the endwhile(j<lenp && (p.charAt(j)=='*' || p.charAt(j)==s.charAt(i) || p.charAt(j)=='?') ){j++;}if(j>=lenp-1){res = true;}else{res = false;}break;}else if(i==lens-1 && j==lenp-1){//both get the endif(s.charAt(i)==p.charAt(j) || p.charAt(j) == '?'){res = true;return res;}}if(s.charAt(i)==p.charAt(j)||p.charAt(j)=='?'){ //loop to comparei++;j++;}else{res = false;break;}}return res;}public boolean isMatch(String s, String p) throws InterruptedException{boolean res = subMatch(s,p,0,0);return res;}public static void main(String[] args) throws InterruptedException{//String s = "abcdefga";//String p = "ab?*g*a";//String s = "abcdefga";//String p = "ab?*g*";//String s = "aaaba";//String p = "a*?a*b*a";//String p = "aaa***ba";//String s = "abab";//String p = "*?*ba*?*";//String p = "***ab***";//String s = "abc12abc1d1dabc1d1e";//String p = "*abc?d?*e";String s = "abab1";String p = "*?*ba*??*";//String s = "ab";//String p = "??";WildcardMatching wm = new WildcardMatching();System.out.println(s+"\n"+p+"\n");boolean res = wm.isMatch(s,p);System.out.println("\nres: "+res);}}
注:可参考main中的s、p的赋值做单元测试;
---------------------------------------------------------------------------------------------------
本文链接:http://blog.csdn.NET/karen0310/article/details/75053593
请尊重作者的劳动成果,转载请注明出处!
---------------------------------------------------------------------------------------------------
阅读全文
0 0
- [LeetCode]44. Wildcard Matching 深入浅出讲解和代码示例
- LeetCode --- 44. Wildcard Matching
- [Leetcode] 44. Wildcard Matching
- Leetcode 44. Wildcard Matching
- leetcode 44. Wildcard Matching
- Leetcode 44. Wildcard Matching
- Leetcode:44. Wildcard Matching
- LeetCode 44. Wildcard Matching
- leetcode.44. Wildcard Matching
- LeetCode 44. Wildcard Matching
- Leetcode-44. Wildcard Matching
- [LeetCode] 44. Wildcard Matching
- [leetcode] 44. Wildcard Matching
- [LeetCode]--44. Wildcard Matching
- LeetCode 44. Wildcard Matching
- leetcode 44. Wildcard Matching
- LeetCode 44. Wildcard Matching
- 44. Wildcard Matching -- LeetCode
- Centos6.8 离线安装nginx
- 查找——顺序查找
- hdu1565 轮廓线动态规划
- easyui的tabs标签不重复打开的方法
- IntelliJ IDEA 专业版注册破解
- [LeetCode]44. Wildcard Matching 深入浅出讲解和代码示例
- Die.Welt.Kompakt.
- pip 安装 beautifulsoup4
- #python学习笔记#使用python爬取网站数据并保存到数据库
- 最小生成树:POJ1251-Jungle Roads(最小生成树的模板)
- JWT 概念以及Cookie+Session解决的问题
- IntelliJ IDEA启动Tomcat后,却无法访问Tomcat主页
- 黑框框里的三子棋
- python——快速读取excel文件并插入数据库