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));
}
}
}