这是《剑指Offer》的第十九题:

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

我们先来说这道题的解法,然后再来说它带给我的一些启示。

我们定义字符串为 s,模式为 p。总的思路则是,如果当前 s 和 p 对应的字符相匹配,那么我们继续匹配它们剩下的字符。 所以我们应该用递归的方法来解决问题。接下来,我们可以根据第二个字符是否是 '*' 来将问题分为两种情况。 这里的“第二个字符”指的是,我们把此时正在比较的字符称之为“第一个字符”,那么它的下一个字符就是“第二个字符”。

  • 如果第二个字符是 '*':
    • 如果第一个字符相等:
      • 我们从 s + 1 和 p + 2 处继续比较,即 * 前的字符只重复一次
      • 我们从 s + 1 和 p 处继续比较,即 * 前的字符可以重复多次
      • 我们从 s 和 p + 2 处继续比较,即 * 前的字符重复了 0 次
    • 让 s 不变,直接从 * 后的字符开始比较,即 * 前的字符重复了 0 次
  • 继续比较 s 和 p 的下一个字符

经过这样的分析,我们就不难写出代码了,这是我的提交记录。

以上是在说这道题的解法,下面我们来聊聊它对我的一些启示。

首先,“递归”。我在一开始写这道题的时候,没有想到用“递归”来去分析问题,而是用循环。但是通过 阅读书上的解法,我发现解决这种问题,“递归”是一种天然的思路。你看,我们做字符串匹配,不就是 先匹配第一个字符,然后再对它们的子字符串进行匹配吗?所以我觉得我看到这个问题的时候没有第一 时间反应出用“递归”来进行分析,说明我对“递归”这种方法还是不够熟悉,不能够灵活应用它。这是我 之后需要着重加强的一点。

第二,则是对问题的分类能力。你看,人家的解法就可以直接从“第二个字符是否为“*””入手,从而 自然的把问题解决,反观自己在一开始处理时显得手忙脚乱,十分狼狈。我个人觉得,这是因为无法 准确的抓住问题的要点导致的。而改进的方法则是多思考,多总结,多练习。

以上。