LeetCode进阶之路( Wildcard Matching)

本文介绍了一种实现通配符匹配的算法,该算法支持 '?' 和 '*' 的匹配,其中 '?' 可以匹配任意单个字符,而 '*' 可以匹配任意序列的字符。通过递归方法实现了对整个输入字符串的匹配,并提供了详细的代码示例。

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") → 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

题目:和之前的Regular Expression Matching类似,但是在做这道题目时差点没崩溃,感觉复杂了很多。

思路:用递归,遇到*特殊处理。直接贴代码吧,自己的思路实在是太乱了,也许过个两天在来看这份代码估计就看不明白了,网友也别看我的这份代码,贴上来只为反省,尤其是看了其他人的解法,捂脸三分钟。

public boolean isMatch(String s, String p) {
		if(p.length() == 0 && s.length() != 0) {
			boolean flag = true;
			for(int i = 0; i<s.length();i++) {
				if(s.charAt(i) != '*') {
					flag = false;
					return false;
				}
			}
			if(flag) {
				return true;
			}
		}
		
		if(s.length() == 0 && p.length() != 0) {
			boolean flag = true;
			for(int i = 0; i<p.length();i++) {
				if(p.charAt(i) != '*') {
					flag = false;
					return false;
				}
			}
			if(flag) {
				return true;
			}
		}
       if(p.length() == 0 && s.length() == 0) {
    	   return true;
       }
       
       if(p.length() == 1 || p.charAt(1) != '*') {
    	   if(p.length() == 1) {
    		   if(p.charAt(0) == '*') {
    			   return true;
    		   }
    		   if(s.length() > 1 || (p.charAt(0) != '?' && p.charAt(0)!= s.charAt(0))) {
    			   return false;
    		   }
    	   } else {
    		   if(p.charAt(0) != '?' && p.charAt(0) != s.charAt(0) && p.charAt(0)!='*') {
    			   return false;
    		   } else  if(p.charAt(0) == '*'){
    			   if(isMatch(s.substring(0), p.substring(1))){
    				   return true;
    			   } else {
    				   return false;
    			   }
    		   }else{
    			   if(isMatch(s.substring(1), p.substring(1))){
    				   return true;
    			   } else {
    				   return false;
    			   }
    		   }
    	   }
       } else {
    	   if(p.charAt(0) != '?' && p.charAt(0) != s.charAt(0) && p.charAt(0) != '*') {
    		   return false;
    	   } else {
    		   if(p.charAt(p.length()-1) == '*') {
    			   return true;
    		   }
    		   for(int i = s.length() - 1; i > 0;i--) {
    			   if(p.charAt(2) == '?'|| s.charAt(i) == p.charAt(2)) {
    				   if(isMatch(s.substring(i+1), p.substring(3))){
    					   return true;
    				   } else {
    					   return false;
    				   }
    			   }
    		   }
    		   return false;
    	   }
       }
       return true;
    }
下面是百度的一个思路,这就是差距,差的不止十万八千里,革命还未成功,还需继续努力。

public boolean isMatch(String s, String p) {
    if (s == null || p == null) return false;
    if (s.equals(p)) return true;
    int m = s.length();
    int n = p.length();
    int posS = 0;
    int posP = 0;
    int posStar = -1;
    int posOfS = -1;
    //if posS == posP || posP == '?', ++posS and ++posP.
    //posOfS, posStar, record the positon of '*' in s and p, ++posP and go on.
    //if not match, go back to star, ++posOfS
    while (posS < m) {
      if (posP < n && (s.charAt(posS) == p.charAt(posP) || p.charAt(posP) == '?')) {
        ++posS;//如果p为?,或者s、p相等,就继续往下遍历
        ++posP;
      }
      else if (posP < n && p.charAt(posP) == '*') {//如果p是*
        posStar = posP;//位置标志posStar
        posOfS = posS;//s位置标志posOfS
        ++posP;//p移到下一位
        continue;
      }
      else if (posStar != -1) {//如果这一位既不满足上面两个条件,就是要处理*号这个特殊位置,开始遍历s,直到找到和p位置一样的值,
        posS = posOfS;
        posP = posStar + 1;
        ++posOfS;
      }
      else {
        return false;//如果一直找不到,就返回false;
      }
    }
    while (posP < n && p.charAt(posP) == '*') {这种情况是处理p后面有一长串*
      ++posP;
    }
  
    return posS == m && posP == n;//如果两者都能狗顺利遍历完,则相等。
  }


今天七夕,想和一个女生说一声对不起,因为我的不懂事、自私,辜负了她。很好的一个女生,我却没有好好珍惜,以前我总是那么不懂事,不会体谅她,不会包容她。人总是要等到失去之后才会明白,有些东西一旦失去,就永远回不来了。永远要记住,不要让你在乎的人失望,更不要辜负他们。




评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值