WildcardMatching和Regex,通配符匹配和正则表达式匹配

WildcardMatching:通配符匹配

算法分析:

1. 二个指针i, j分别指向字符串、匹配公式。

2. 如果匹配,直接2个指针一起前进。

3. 如果匹配公式是*,在字符串中依次匹配即可。

 注意记录上一次开始比较的位置

Implement wildcard pattern matching with support for '?' and '*'

'?' Matches any single character.

'*' Matches any sequence of characters (including the empty sequence).

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
public class WildcardMatching {
    public boolean isMatch(String s, String p) 
    {
        if (s == null || p == null) 
        {
            return false;
        }
        
        int indexS = 0;
        int indexP = 0;
        
        int lenS = s.length();
        int lenP = p.length();
        
        int preP = -1;//记录通配符为*时通配字符串的下标
        int preS = -1;//记录通配符为*时要匹配的字符串下标
        
        while (indexS < lenS)
        {
        	//非*匹配时,indexS和indexP同时移动
            if (indexP < lenP && (p.charAt(indexP)==s.charAt(indexS)||p.charAt(indexP)=='?')) 
            {
                indexP++;
                indexS++;
            } 
           
            //碰到*,记录此时p,s的下标
            else if (indexP < lenP && p.charAt(indexP) == '*') 
            {
                preS = indexS;
                preP = indexP;
                
                // p比较指针后移,假设*匹配空字符串
                indexP++;
            } 
            
            
            else if (preP != -1)//尝试匹配*
            {
                indexP = preP;//p回退到*位置
                indexP++;
                
                preS++;//尝试匹配*,每次移动一个字符,然后比较p的*后面字符和s剩下的字符,如果不匹配,回退到*的位置
                indexS = preS;
            } 
            
            else 
            {
                return false;
            }
        }
        
        while (indexP < lenP)
        {
            if (p.charAt(indexP) != '*') 
            {
                return false;
            }
            indexP++;
        }
        
        return true;
    }
    //通过例子aab和*ab来模拟过程
    public static void main(String[] args) {
		WildcardMatching wm = new WildcardMatching();
		System.out.println(wm.isMatch("aab", "*ab"));
	}
}



Regex:正则表达式匹配

问题描述: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

算法分析:.*可以匹配任意字符串,例如ab匹配.*,不是说让.匹配完a然后再去匹配*,而是*匹配的是.,也就是说(.*)==(..........),所以.*匹配所有字符串。

利用动态规划,对于匹配字符串p,讨论三种情况,p长度为0,p长度为1,p的长度大于1(p的第二字符串为*,p的第二个字符串不为*)

//动态规划
public class Regex2 {
	public boolean isMatch(String s, String p) {
		// p长度为0,边界条件。
		if (p.length() == 0) {
			return s.length() == 0;
		}
	 
		// p长度为1,边界条件。
		if (p.length() == 1) {
	 
			// s长度为0
			if (s.length() < 1) {
				return false;
			}
	        //首元素匹配有两种情况
			// 如果p为.则s第一个元素和p一定匹配,如果p的第一个元素和s的第一元素相同,也一定匹配。
			else if ((p.charAt(0) != s.charAt(0)) && (p.charAt(0) != '.')) {
				return false;
			}
	 
			// 否则除了第一个匹配的元素外,比较其他的元素,动态规划的思想。
			else {
				return isMatch(s.substring(1), p.substring(1));
			}
		}
	 
		// p的第二个元素不是*,*代表0个或多个前面的元素
		if (p.charAt(1) != '*')
		{
			if (s.length() < 1) 
			{
				return false;
			}
			else if ((p.charAt(0) != s.charAt(0)) && (p.charAt(0) != '.'))
			{
				return false; 
			} 
			else 
			{
				return isMatch(s.substring(1), p.substring(1));
			}
		}
	 
		else  //p的第二个元素是*
		{
			//*代表0个前面的元素
			if (isMatch(s, p.substring(2))) 
			{
				return true;
			}
	 
			//*代表一个或多个前面的元素
			//遍历s,如果s的i元素等于p的第一个元素,或者p的第一个元素为.,匹配s的i+1和p的第三个元素后的字符串
			for(int i = 0; 
					i<s.length() && (s.charAt(i) == p.charAt(0) || (p.charAt(0) == '.'));
					i ++ )
			{
				if(isMatch(s.substring(i + 1), p.substring(2)))
				{
					return true;
				}
			}
			return false;
		}
	}
	public static void main(String[] args)
	{
		Regex2 reg2 = new Regex2();
		System.out.println(reg2.isMatch("aaba", ".*"));
	}
}
原文地址:https://www.cnblogs.com/masterlibin/p/5744532.html