参考Vosky的博客,网址:https://blog.csdn.net/hk2291976/article/details/51165010.
匹配任意一个字符,*匹配0个或者多个前导字符
*匹配0个或多个前导字符,例如a*,*的前导为a,故0或者多个a,即空字符串、a、aa、aaa、aaa、aaaaa等等
package algorithm;
import java.util.Arrays;
import java.util.regex.Pattern;
import org.junit.Test;
/*
* 正则表达式
*
原题
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). 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”, “a*”) → true
isMatch(“aa”, “.*”) → true
isMatch(“ab”, “.*”) → true
isMatch(“aab”, “c*a*b”) → true
实现一个正则表达式的匹配算法, .匹配任意一个字符,
*匹配0个或者多个前导字符
使用标记匹配算法,从后向前进行匹配
* */
//*匹配0个或多个前导字符,例如a*,*的前导为a,故0或者多个a,即空字符串、a、aa、aaa、aaa、aaaaa等等
public class RegularExpression {
//https://blog.csdn.net/hk2291976/article/details/51165010
//采用动态规划算法,利用空间换取时间,用2维布尔数组,dp[i][j]的含义是s[0,,i]与p[0-j]是否匹配
//1 如果p.charAt(j)==s.charAt(i) ; dp[i][j]=dp[i-1][j-1]
//2 如果p.charAt(j)=='.'; dp[i][j]=dp[i-1][j-1]
//3 如果p.charAt(j)=='*'
//3.1 如果p.charAt(j-1)!=s.charAt(i),则dp[i][j]=dp[i][j-2]
//3.2 如果p.charAt(j-1)=s.charAt(i) 或者 p.charAt(j-1)='.'
//dp[i][j]=dp[i-1][j] //此种情况是 a*匹配多个a
//dp[i][j]=dp[i][j-1] //此是a*匹配一个a
//dp[i][j]=dp[i][j-2] //此时a*匹配0个a
// dp[0][j] = j > 1 && '*' == p[j - 1] && dp[0][j - 2];
// 关系运算符 左结合 < > <= >= instanceof(Java 特有) = = !=
//逻辑运算符 左结合 ! && || ~ & | ^ a
/*
* 采取动态规划算法实现字符串匹配
* 参数:
* 输出:
* */
public static boolean isMatch2(String s,String p){
int m=s.length();
int n=p.length();
//值的初始化
boolean[][] dp=new boolean[m+1][n+1];//默认的初始值均为false
dp[0][0]=true; //全部为空,则匹配
for(int i=1;i<=m;i++){
dp[i][0]=false;
}
//如果源为空串, 则,一定为 a*,如果包含*,则一定与P[0][j-2]同
for(int j=1;j<=n;j++){
dp[0][j]=j>1&&p.charAt(j-1)=='*'&&dp[0][j-2];
}
//下面开始实际值
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(p.charAt(j-1)=='*'){
dp[i][j]=dp[i][j-2]||(p.charAt(j-2)==s.charAt(i-1)||p.charAt(j-2)=='.')&&
(dp[i-1][j]||dp[i][j-1]||dp[i][j-2]);
}else { //不为*
dp[i][j]=(p.charAt(j-1)=='.'||p.charAt(j-1)==s.charAt(i-1))&&dp[i-1][j-1];
// System.out.println("dp["+i+"]["+j+"]="+dp[i][j]);
}
}
}
return dp[m][n];
}
//采取回溯的方法
//用i,j表示当前s和p的字符,我们从后向前匹配
//一、如果j遇到*,
//1 如果s[i]和p[j-1]不相同,则
// myMatch(s,i,p,j)=myMatch(s,i,p,j-2)
//2 如果s[i]==p[j-1]或者p[j-1]=='.'
// myMatch(s,i,p,j)=myMatch(s,i-1,p,j)
//如果遇到的不是*,则比较s[i]和p[j]是否相等,如果不等,则错误
// if(p[j]=='.'||p[j]==s[i])
// return myMatch(s,i-1,p,j-1)
// else return false;
//如果最后j<0,说明p已经匹配完了,如果s匹配完了,则正确。否则错误
private static int FRONT=-1;
public static boolean isMatch(String s,String p){
return myMatch(s,s.length()-1,p,p.length()-1);
}
private static boolean myMatch(String s, int i, String p, int j) {
//System.out.println("开始了----"+i+" "+j);
if(j==FRONT){
//System.out.println("---1=="+i+" "+j);
if(i==FRONT)
return true;
else{
//System.out.println("---2=="+i+" "+j);
return false;
}
}
if(p.charAt(j)=='*'){
//System.out.println("p.charAt(j)==*"+i+" "+j);
if(i>FRONT&&(p.charAt(j-1)=='.'||p.charAt(j-1)==s.charAt(i))){
if(myMatch(s,i-1,p,j)){
return true;
}
}
//System.out.println("myMatch(s,i,p,j-2)"+i+" "+j);
return myMatch(s,i,p,j-2);
}
if(p.charAt(j)=='.'||p.charAt(j)==s.charAt(i)){
//System.out.println("p.charAt(j)=='.'||p.charAt(j)==s.charAt(i)="+i+" "+j);
return myMatch(s,i-1,p,j-1);
}
//System.out.println("---3=="+i+" "+j);
return false;
}
*匹配0个或多个前导字符,例如a*,*的前导为a,故0或者多个a,即空字符串、a、aa、aaa、aaa、aaaaa等等
@Test
public void test(){
//Pattern ptn=Pattern.compile("a*");
String regex=".*runoob.*";
String input="I am noob " +
"from runoob.com.";
regex="a*";
input="";
boolean flag=Pattern.matches(regex,input);
if(flag){
System.out.println("匹配"+" "+regex+" "+input);
}else{
System.out.println("不匹配"+" "+regex+" "+input);
}
}
public static void main1(String[] args) {
// TODO Auto-generated method stub
// isMatch(“aaa”,”aa”) → false
String inputStr="abc";
String pattern="bc";
boolean flag=isMatch("abc","abc");
if(flag==true){
System.out.println("abc"+" abc"+" 测试通过---正确");
}else{
System.out.println("abc"+" abc"+" 测试不****通过");
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
// isMatch(“aaa”,”aa”) → false
String inputStr="abc";
String pattern="bc";
/*
isMatch(“aa”,”a”) → false
isMatch(“aa”,”aa”) → true
isMatch(“aa”, “a*”) → true
isMatch(“aa”, “.*”) → true
isMatch(“ab”, “.*”) → true
isMatch(“aab”, “c*a*b”) → true
*/
boolean flag=isMatch("abc","bc");
if(flag){
System.out.println("abc"+" bc"+" 测试通过");
}else{
System.out.println("abc"+" bc"+" 测试不***通过---正确");
}
flag=isMatch("abc","abc");
if(flag==true){
System.out.println("abc"+" abc"+" 测试通过---正确");
}else{
System.out.println("abc"+" abc"+" 测试不****通过");
}
flag=isMatch("aa","a.");
if(flag==true){
System.out.println("aa"+" a."+" 测试通过------正确");
}else{
System.out.println("aa"+" a."+" 测试不***通过");
}
flag=isMatch("abcde","a*");
//*匹配0个或多个前导字符,例如a*,*的前导为a,故0或者多个a,即空字符串、a、aa、aaa、aaa、aaaaa等等
if(flag==true){
System.out.println("abcde"+" a*"+" 测试通过");
}else{
System.out.println("abcde"+" a*"+" 测试不***通过------正确");
}
flag=isMatch("aa","a");
//*匹配0个或多个前导字符,例如a*,*的前导为a,故0或者多个a,即空字符串、a、aa、aaa、aaa、aaaaa等等
if(flag==true){
System.out.println("aa"+" a"+" 测试通过");
}else{
System.out.println("aa"+" a"+" 测试不***通过------正确");
}
flag=isMatch("aa","aa");
//*匹配0个或多个前导字符,例如a*,*的前导为a,故0或者多个a,即空字符串、a、aa、aaa、aaa、aaaaa等等
if(flag==true){
System.out.println("aa"+" aa"+" 测试通过------正确");
}else{
System.out.println("aa"+" aa"+" 测试不***通过");
}
flag=isMatch("aaa","aa");
//*匹配0个或多个前导字符,例如a*,*的前导为a,故0或者多个a,即空字符串、a、aa、aaa、aaa、aaaaa等等
if(flag==true){
System.out.println("aaa"+" aa"+" 测试通过");
}else{
System.out.println("aaa"+" aa"+" 测试不***通过------正确");
}
flag=isMatch("aa","a*");
//*匹配0个或多个前导字符,例如a*,*的前导为a,故0或者多个a,即空字符串、a、aa、aaa、aaa、aaaaa等等
if(flag==true){
System.out.println("aa"+" a*"+" 测试通过------正确");
}else{
System.out.println("aa"+" a*"+" 测试不***通过");
}
flag=isMatch("aa",".*");
//*匹配0个或多个前导字符,例如a*,*的前导为a,故0或者多个a,即空字符串、a、aa、aaa、aaa、aaaaa等等
if(flag==true){
System.out.println("aa"+" .*"+" 测试通过------正确");
}else{
System.out.println("aa"+" .*"+" 测试不***通过");
}
flag=isMatch("ab",".*");
//*匹配0个或多个前导字符,例如a*,*的前导为a,故0或者多个a,即空字符串、a、aa、aaa、aaa、aaaaa等等
if(flag==true){
System.out.println("ab"+" .*"+" 测试通过------正确");
}else{
System.out.println("ab"+" .*"+" 测试不***通过");
}
flag=isMatch("aab","c*a*b");
//*匹配0个或多个前导字符,例如a*,*的前导为a,故0或者多个a,即空字符串、a、aa、aaa、aaa、aaaaa等等
if(flag==true){
System.out.println("aab"+" c*a*b"+" 测试通过------正确");
}else{
System.out.println("aab"+" c*a*b"+" 测试不***通过");
}
}
}