编程题--正则表达式

题目描述

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

分析:

首先,考虑特殊请况

  1. 两个字符串都为空,返回true.
  2. 当第一个字符串不空,而第二个字符串空了,返回false(因为这样,就无法匹配成功了,而如果第一个字符串空了,第二个字符串非空,还可能匹配成功的。Eg: a*a*a*a*)

正常情况:每次分别在str和pattern中取一个字符进行比较,如果匹配,则匹配下一个字符,否则,返回不匹配。

分析:递归实现

   设匹配递归函数 match(str, pattern)。

1.  如果模式匹配字符的下一个字符是‘*’:

如果pttern当前字符和str的当前字符匹配,:有以下三种可能情况

  •     pttern当前字符能匹配 str 中的 0 个字符:match(str, pattern+2)
  •     pttern当前字符能匹配 str 中的 1 个字符:match(str+1, pattern+2)
  •     pttern当前字符能匹配 str 中的 多 个字符:match(str+1, pattern)

 如果pttern当前字符和和str的当前字符不匹配:

  •   pttern当前字符能匹配 str 中的 0 个字符:(str, pattern+2)

2.  如果模式匹配字符的下一个字符不是‘.’:

  对于 ‘.’ 的情况比较简单,’.’ 和一个字符匹配 match(str+1, pattern+1)

3. 如果模式匹配字符的下一个字符是正常字符,且 *str == *pattern,

    递归下一个字符 :match(str+1, pattern+1)

 

实现

注:上边这几类情况,再代码实现中,可以进行归类合并,详见下面的代码:

//正则表达式的匹配
	//注:空字符串和“.*”是匹配的
	bool match(char* str, char* pattern)
    {
        //特殊情况处理
		//如果str和pattern都为NULL, 返回true
        if(*str == '\0' && *pattern == '\0')
		{
			return true;
		}
		//str不为NULL, pattern为NULL,一定不匹配,返回false.
		//注:str为NULL, pattern不为NULL时,可能匹配。 eg: a*a*a*a*
		if(*str != '\0' && *pattern == '\0')
		{
			return false;
		}

		//递归进行处理(正常情况)
		if(*(pattern+1) == '*') //pattern可匹配0次,1次或多次
		{
			if(*pattern == *str || (*str != '\0' && *pattern == '.'))
			{
				return match(str,pattern+2) //*pattern == *str请况下,匹配0个
					|| match(str+1,pattern); //匹配多个
			}
			else //*pattern != *str请况下匹配0次,pattern+2
			{
				return match(str,pattern+2);
			}
		}

        //pattern下一个字符为. 或正常字符即(*str == *pattern)
		if((*str != '\0' && *pattern == '.') || (*str == *pattern))
		{
			return match(str+1, pattern+1);
		}

		return false;
    }

总结

      在写这道题时,首先理解什么是正则表达式,对“*”和“.”的匹配模式进行理解,然后对各种情况进行分析,归类。再具体写代码实现。

图解

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值