剑指offer47--正则表达式匹配


一、题目


题目:请实现一个函数用来匹配包含‘.’和‘*’的正则表达式。模式中的字符’.’表示任意一个字符,而‘*’表示它前面的字符可以出现任意次(含0次)。本题中,匹配是指字符串的所有字符匹配整个模式。



二、举例




例如,字符串“aaa”与模式“a.a”和“ab*ac*a”匹配(b和c都可以是0个),但与“aa.a”及“ab*a”均不匹配。



三、思想


(1)对两个字符串进行逐个字符的匹配,两是否同时到达末尾,同时到达则成功,否则匹配失败

(2)当模式字符串的下一个字符是*号时,可以衍生出如下三种情况,都是可以的
<1>匹配+1,模式+2(如:匹配为ab,模式为a*)
<2>匹配+1,模式+0(如:匹配为aa/*a,模式为a*)
<3>匹配+0,模式+2(如:匹配为ba,模式为a*)

(3)当前模式字符是'.'号时,都向前移动一位,注意的时,这一步一定要在判断*号的后面,否则'.*'这种情况下会出错



四、程序


package 剑指offer;
/*题目:请实现一个函数用来匹配包含‘.’和‘*’的正则表达式。模式中的字符’.’表示任意一个字符,
 *而‘*’表示它前面的字符可以出现任意次(含0次)。本题中,匹配是指字符串的所有字符匹配整个模式。
 *例如,字符串“aaa”与模式“a.a”和“ab*ac*a”匹配,但与“aa.a”及“ab*a”均不匹配。*/

/*题意:点可以表示任意字符,星*表示前一个字符可以出现0--n次,那么用递归来解,条件是str串和pattern串到达结尾,或者str串结尾了,
 *pattern串没有结尾,都退出。而递归的条件是:遇到*,则三个出口,(str+1,pattern+2),(str+1,pattern+2),(str,pattern+2),(str+1,pattern);*/
public class Test52 {

	public static boolean matchString(String input, String pattern){
		if(input == null || pattern == null){
			return false;
		}
		
		return matchByChar(input, 0, pattern, 0);
	}
	
	public static boolean matchByChar(String input , int in, String pattern, int pa){
		// 都到达结尾,说明匹配成功
		if(in >= input.length() && pa >= pattern.length()){
			return true;
		}
		
		// 只有模式串或者匹配串到达结尾,匹配失败
		if(in != input.length() && pa >= pattern.length()){
			return false;
		}
		
        // 匹配串已经结束
        if (in >= input.length()) {
            return false;
        }
        
		// 如果模式的下一个元素是'*'
		if (pa + 1 < pattern.length() && pattern.charAt(pa + 1) == '*'){
            // 匹配串已经结束
            if (in >= input.length()) {
                return matchByChar(input, in, pattern, pa + 2);
            }
            
            else {
                if (pattern.charAt(pa) == input.charAt(in) || pattern.charAt(pa) == '.') {
                    return
                            // 匹配串向后移动一个位置,模式串向后移动两个位置
                    		matchByChar(input, in + 1, pattern, pa + 2)
                                    // 匹配串向后移动一个位置,模式串不移动
                                    || matchByChar(input, in + 1, pattern, pa)
                                    // 匹配串不移动,模式串向后移动两个位置
                                    || matchByChar(input, in, pattern, pa + 2);
                } else {
                    return matchByChar(input, in, pattern, pa + 2);
                }
            }
		}
		
		// 如果模式的元素和匹配字符的元素相等或者是'.'号
        if (input.charAt(in) == pattern.charAt(pa) || pattern.charAt(pa) == '.') {
            return  matchByChar(input, in + 1, pattern, pa + 1);
        }
        
        //为什么要将判断'.'号放到判断'*'号的后边,因为当模式中是.*这种情况的时候,如果先判断.好的话就会直接跳过了.号
        //那么就不能正常正常的进行判断了
		return false;
	}
	
	
    public static void main(String[] args) {
        
        System.out.println(matchString("aaa", "aa*") + "[" + true + "]");
        System.out.println(matchString("aaa", "aa.a") + "[" + false + "]");
        System.out.println(matchString("aaa", "a.a") + "[" + true + "]");
        System.out.println(matchString("aaa", "a*a") + "[" + true + "]");
        System.out.println(matchString("aaa", "ab*a") + "[" + false + "]");
        System.out.println(matchString("aaa", "ab*ac*a") + "[" + true + "]");
        System.out.println(matchString("aaa", "ab*a*c*a") + "[" + true + "]");
        System.out.println(matchString("aaa", ".*") + "[" + true + "]");
    }
}


----------out------------

true[true]
false[false]
true[true]
true[true]
false[false]
true[true]
true[true]
true[true]




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值