《剑指offer》面试题19:正则表达式匹配

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


解题思路:

这里匹配情况分两种:

  1. 模式中没有 *: 直接逐个匹配,’.'可以看作任意字符
  2. 模式中有 * :在第一个字符匹配,第二个字符是’*'的情况下,又可以分成三种情况:
    ①情况1:指向字符串的指针移动一次,指向模式串的指针移动两次
    在这里插入图片描述
    ②情况2:指向字符串的指针移动一次,指向模式串的指针不动
    在这里插入图片描述
    ③情况3:指向字符串的指针不动,指向模式串的指针移动两次
    在这里插入图片描述

基于以上分析,java参考代码如下:

public class RegularExpressionsMatching {
    public static boolean match(String str,String pattern){
        if(str==null || pattern==null)
            return false;
        return matchCore(new StringBuilder(str),0,new StringBuilder(pattern),0);
    }
    //StringBuilder的作用:
    public static boolean matchCore(StringBuilder str,Integer strIndex,StringBuilder pattern, Integer patternIndex){
        //如果匹配串和模式串都匹配结束
        if(strIndex==str.length() && patternIndex==pattern.length())
            return true;
        if(strIndex!=str.length() && patternIndex==pattern.length())
            return false;
        if(strIndex==str.length() && patternIndex!=pattern.length()) {
            if(patternIndex+1<pattern.length()&&pattern.charAt(patternIndex+1)=='*')
                return matchCore(str,strIndex,pattern,patternIndex+2);
            else
                return false;
        }
        //如果模式串的第二个字符不是*或者已经只剩一个字符了
        if(patternIndex==pattern.length()-1|| pattern.charAt(patternIndex+1)!='*'){
            if(pattern.charAt(patternIndex)=='.' || pattern.charAt(patternIndex)==str.charAt(strIndex))
                return matchCore(str,strIndex+1,pattern,patternIndex+1);
            else
                return false;
        }
        //如果模式串的第二个字符是*
        else{
            if(pattern.charAt(patternIndex)=='.'||pattern.charAt(patternIndex)==str.charAt(strIndex))
                return matchCore(str,strIndex+1,pattern,patternIndex)
                        ||matchCore(str,strIndex+1,pattern,patternIndex+2)
                        ||matchCore(str,strIndex,pattern,patternIndex+2);
            else
                return matchCore(str,strIndex,pattern,patternIndex+2);
        }
    }
    public static void main(String[] args){
        System.out.println(match("aaa","a.a"));//true
        System.out.println(match("aaa","ab*ac*a"));//true
        System.out.println(match("aaa","aa.a"));//false
        System.out.println(match("aaa","ab*a"));//false
    }
}

C++参考代码如下:

bool matchCore(const char* str, const char* pattern) 
{ 
	if (*str == '\0' && *pattern == '\0') 
		return true;
		
	if (*str != '\0' && *pattern == '\0') 
		return false;
	
	/*第二个字符是 '*' 的情况*/
	if (*(pattern + 1) == '*') 
	{ 
		if (*pattern == *str || (*pattern == '.' && *str != '\0')) 
			return matchCore(str + 1, pattern + 2) //情况1 
			|| matchCore(str + 1, pattern) //情况2 
			|| matchCore(str, pattern + 2); //情况3 
		else 
			return matchCore(str, pattern + 2); 
	} 
	
	if (*str == *pattern || (*pattern == '.' && *str != '\0')) 
		return matchCore(str + 1, pattern + 1); 

	return false; 
} 

bool match(const char* str, const char* pattern) 
{ 
	if (str == nullptr || pattern == nullptr) 
		return false; 

	return matchCore(str, pattern); 
}
测试用例:

a.功能测试(模式字符串里包含普通字符:‘.’和‘*’;模式字符串和输入字符串匹配/不匹配)。
b.特殊输入测试(输入字符串和模式字符串时nullptr、空字符串)。

参考:

https://blog.csdn.net/Tianzez/article/details/79224114

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值