LeetCode刷题day009 (Jieky)

LeetCode第10题

/*
Given an input string (s) and a pattern (p). implement regular expression matching with support for '.' and '*'. 

'.' Matches any single character.
'*' Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).

Note: 
s could be empty and contains only lowercase letters a-z
p could be empty and contains only lowercase letters a-z, and characters like . or *

Example 1: 
Input:
s="aa"
p="a"
Output: false 
Explanation: "a" does not match the entire string "aa".

Example 2: 
Input: 
s="aa"
p= "a*"
Output: true 
Explanation: '*' means zero or more of the precedeng element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".

Example 3: 
Input: 
s= "ab"
p=".*"
Output: true 
Explanation: ".*" means "zero or more (*) of any character (.)".

Example 4: 
Input:
s = "aab"
p= "c*a*b"
Output: true 
Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore it matches "aab".

Example 5: 
Input:
s= "mississippi"
p= "mis*is*p*."
Output: false
*/

public class RegularExpressionMatching{
	public static void main(String[] args){
		
		String s1 = "aa";
		String p1 = "a";
		
		String s2 = "aa";
		String p2 = "a*";
		
		String s3 = "ab";
		String p3 = ".*";
		
		String s4 = "aab";
		String p4 = "c*a*b";
		
		String s5 = "mississippi";
		String p5 = "mis*is*p*.";
		
		String s6 = "a";
		String p6 = "a";
		
		String s7 = "a";
		String p7 = "b";
		
		String s8 = "aa";
		String p8 = ".*";
		
		// 正则表达式能否以*开头?
		String s11 = "";
		String p11 = "***";
		
		RegularExpressionMatching rem = new RegularExpressionMatching();
		boolean ret = rem.isMatch01(s11,p11);
		System.out.println(ret);
		// System.out.println("123".substring(3).equals("123".substring(3)));
		// System.out.println("123".substring(3).equals(""));
	}
	
	// 解决带bug递归,变为正确的递归
	public boolean isMatch03(String text, String pattern) {
        if (text == null || pattern == null) return false;

        // 停止条件,text、pattern都为空
        if (text.isEmpty()) {
            if (pattern.isEmpty()){
                return true;
            }else{
                if (pattern.length()%2 != 0) return false;
                for (int i = 1;i<pattern.length();i+=2){
                    if (pattern.charAt(i) != '*') return false;
                }
                return true;
            }
        }

        // 判断首字符是否相等
        boolean firstEqual = (!pattern.isEmpty() && (text.charAt(0) == pattern.charAt(0) || pattern.charAt(0) == '.'));

        // *前面一定有字符,即当pattern.length() >= 2时,才考虑*的存在
        if (pattern.length() >= 2 && pattern.charAt(1) == '*'){
            // *表示前一个字符的0次及以上的重复,前面判断0次情况,后面判断1次及以上情况(接下来又是,前面判断0次情况,后面判断1次及以上)
            // 这两种情况有一个满足即表示继续匹配
            return (isMatch03(text,pattern.substring(2))) || (firstEqual && isMatch03(text.substring(1),pattern));
        }else{
            // 字符串的最后一个字符是""(即空串,index = StringObject.length())
            return firstEqual && isMatch03(text.substring(1), pattern.substring(1));
        }
    }
	
	// 带bug递归
	public boolean isMatch02(String text, String pattern) {
        if (text == null || pattern == null) return false;
		/*
		s2、p2为例:s = "aa";p = "a*";
		s2、p2为例:s = "aa";p = "a*";
		①firstEqual == true;
		①isMatch(text,pattern.substring(2)) -> s = "aa";p = "";
			②firstEqual = false;
			②firstEqual && isMatch(text.substring(1), pattern.substring(1)); -> return false;
		①firstEqual && isMatch(text.substring(1),pattern) -> s = "a";p = "a*";
			②firstEqual = true;
			②isMatch(text,pattern.substring(2)) -> s = "a";p = "";
				③firstEqual = false;
				③firstEqual && isMatch(text.substring(1), pattern.substring(1)); -> return false;
			②firstEqual && isMatch(text.substring(1),pattern) -> s = "";p = "a*";
				// 这里就没有考虑s = ""且p = "a*"的情况;
				③if (text.isEmpty()) return false;
				// 问题就出现在这,无法进行下面的程序
				③firstEqual == false;
				③isMatch(text,pattern.substring(2)) -> s = "";p = "";
					④if (pattern.isEmpty()) return true;
		*/
		
		// 停止条件,text、pattern都为空
		if (text.isEmpty()){
			// 这里存在bug,pattern == "a*" 或 ".*"时会给出错误的结果
			return pattern.isEmpty();
		}
		
		// 判断首字符是否相等
		boolean firstEqual = (!pattern.isEmpty() && (text.charAt(0) == pattern.charAt(0) || pattern.charAt(0) == '.'));
		
		// *前面一定有字符,即当pattern.length() >= 2时,才考虑*的存在 
		if (pattern.length() >= 2 && pattern.charAt(1) == '*'){
			// *表示前一个字符的0次及以上的重复,前面判断0次情况,后面判断1次及以上情况(接下来又是,前面判断0次情况,后面判断1次及以上)
			// 这两种情况有一个满足即表示继续匹配
			return (isMatch02(text,pattern.substring(2))) || (firstEqual && isMatch02(text.substring(1),pattern));
		}else{
			// 字符串的最后一个字符是""(即空串,index = StringObject.length())
			return firstEqual && isMatch02(text.substring(1), pattern.substring(1));
		}
    }
	
	// 使用递归
	public boolean isMatch01(String text, String pattern) {
        if (text == null || pattern == null ) return false;
		// 以*开头的字符串应该是不行的
		/*
		s2、p2为例:s = "aa";p = "a*";
		①firstEqual == true;
		①isMatch(text,pattern.substring(2)) -> s = "aa";p = "";
			②if (pattern.isEmpty()) return false;
		①firstEqual && isMatch(text.substring(1),pattern) -> s = "a";p = "a*";
			②firstEqual == true;
			②isMatch(text,pattern.substring(2)) -> s = "a";p = "";
				③if (pattern.isEmpty()) return false;
			②firstEqual && isMatch(text.substring(1),pattern) -> s = "";p = "a*";
				//这个条件不满足,继续执行下面的语句
				③//if (pattern.isEmpty()) return text.isEmpty();
				③firstEqual == false;
				③isMatch(text,pattern.substring(2)) -> s = "";p = "";
					④if (pattern.isEmpty()) return true;
		*/
		
		// 停止条件,text、pattern都为空,
		// text、pattern的顺序不能调换 
		if (pattern.isEmpty()) return text.isEmpty();
		
		// 判断首字符是否相等
		boolean firstEqual = (!text.isEmpty() && (text.charAt(0) == pattern.charAt(0) || pattern.charAt(0) == '.'));
		
		// *前面一定有字符,即当pattern.length() >= 2时,才考虑*的存在 
		if (pattern.length() >= 2 && pattern.charAt(1) == '*'){
			// *表示前一个字符的0次及以上的重复,前面判断0次情况,后面判断1次及以上情况(接下来又是,前面判断0次情况,后面判断1次及以上)
			// 这两种情况有一个满足即表示继续匹配
			return (isMatch01(text,pattern.substring(2))) || (firstEqual && isMatch01(text.substring(1),pattern));
		}else{
			// 字符串的最后一个字符是""(即空串,index = StringObject.length())
			return firstEqual && isMatch01(text.substring(1), pattern.substring(1));
		}
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值