美文网首页数据结构和算法
剑指offer - 正则表达式匹配

剑指offer - 正则表达式匹配

作者: Longshihua | 来源:发表于2019-07-21 08:16 被阅读0次

题目

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

例如,字符串aaa与模式a.aab*ac*a匹配,但与aa.aab*a均不匹配。

  • aaaa.a相匹配,那是因为.表示任意一个字符,即当.a时,两个字符串自然相等,匹配传给。
  • aaaab*ac*a匹配,那是因为*表示它前面的字符可以出现任意次(含0次),即当字符串ab*ac*a中*前面的字符出现0次时,ab*ac*a正好为aaa
  • aa.aab*a很显然是不匹配的

思路

总的思路:每次从字符串里拿出一个字符和模式中的字符去匹配

1、当模式中的第二个字符不是*

  • 如果字符串第一个字符和模式中的第一个字符相匹配,那么字符串和模式都后移一个字符,然后匹配剩余的。
  • 如果字符串第一个字符和模式中的第一个字符相不匹配,直接返回false

2、当模式中的第二个字符是*

如果字符串第一个字符跟模式第一个字符不匹配,则模式后移2个字符,继续匹配。
如果字符串第一个字符跟模式第一个字符匹配,可以有2种匹配方式:

  • 字符串后移1字符,模式后移2字符(相当于*被忽略);
  • 字符串后移1字符,模式不变,即继续匹配字符下一位,因为*可以匹配多位;

具体例子分析

如何匹配一个字符:如果模式中的字符ch'.',那么它可以匹配字符串中的任意字符。如果模式中的字符ch不是'.',而且字符串中的字符也是ch,那么它们相互匹配。当字符串中的字符和模式中的字符相匹配时,接着匹配后面的字符

当模式中的第二个字符不是*时,问题要简单很多。如果字符串中的第一个字符和模式中的第一个字符相匹配,那么在字符串和模式上都后移一个字符,然后匹配剩余的字符串和模式。如果字符串中的第一个字符和模式中的第一个字符不相匹配,则直接返回false

当模式中的第二个字符是*时,问题要复杂一些,因为可能有多种不同的匹配方式。一种选择是在模式上向后移动两个字符。这相当于*和它前面的字符被忽略了,因为*可以匹配字符串的0个字符。

如果模式中的第一个字符和字符串中的第一个字符相匹配,则在字符串上后移一个字符,而在模式上有两种选择:可以在模式上向后移动两个字符,也可以保持模式不变

如下图,当匹配进入状态2并且字符串的字符是'a'时,我们有两种选择:可以进入状态3(在模式上向后移动两个字符),也可以回到状态2(模式保持不变)

download.jpg

算法实现

bool matchCore(char *str, char *pattern);

bool match(char *str, char *pattern)
{
    // 任意字符串为空,匹配失败
    if (str == nullptr || pattern == nullptr)
        return  false;

    return  matchCore(str, pattern);
}

bool matchCore(char *str, 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) || // 移动下一个状态
            matchCore(str + 1, pattern) || // 保持当前状态
            matchCore(str, pattern + 2); // 忽略*
        else
            return matchCore(str, pattern + 2); // 忽略*
    }

    // 如果当前字符的下一个字符不是*,并且字符相等,或者当字符串未结束的情况下,模式字符为.,那么当前字符匹配成功,进行下一个字符匹配
    if (*str == *pattern || (*pattern == '.' && *str != '\0'))
        return matchCore(str + 1, pattern + 1);

    return false;
}

参考

《剑指offer》

相关文章

  • 正则表达式匹配

    《剑指offer》面试题19:正则表达式匹配 题目:请实现一个函数用来匹配包括'.'和''的正则表达式。模式中的字...

  • 字符串

    剑指offer所有的题目总结 牛客 正则表达式的匹配 leetcode的题目,解析描述更加全面 https://l...

  • 剑指offer第二版-19.正则表达式匹配

    本系列导航:剑指offer(第二版)java实现导航帖 面试题19:正则表达式匹配 题目要求:实现正则表达式中.和...

  • 表示数值的字符串

    《剑指offer》面试题20:正则表达式匹配 题目:请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例...

  • [剑指offer] 正则表达式匹配

    本文首发于我的个人博客:尾尾部落 题目描述 请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'....

  • 剑指offer | 正则表达式匹配

    正则表达式匹配 请实现一个函数来匹配包含"."和"*"的正则表达式。模式中的字符"."表示任意一个字符,而"*"表...

  • [剑指Offer]正则表达式匹配

    本文首发于我的个人博客Suixin’s Blog原文: https://suixinblog.cn/2019/02...

  • 剑指offer - 正则表达式匹配

    题目 请实现一个函数用来匹配包含.和*的正则表达式。模式中的字符.表示任意一个字符,而*表示它前面的字符可以出现任...

  • 全网最全剑指offer题目解答

    【剑指offer】Java版代码(完整版) 【剑指offer】1-10题 【剑指offer】11-20题 【剑指o...

  • 剑指offer|51-60题解题思路及代码(Java版)

    剑指offer51到60题总览: 构建乘积数组 正则表达式匹配 表示数值的字符串 字符流中第一个不重复的字符 链表...

网友评论

    本文标题:剑指offer - 正则表达式匹配

    本文链接:https://www.haomeiwen.com/subject/poysjqtx.html