剑指Offer——正则表达式匹配

tech2026-08-12  1

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

方法:有两个指针s和p,s指向字符串,p指向模式

1.首先我们分析出现'.'的情况,从题目中可以知道,这个符号可以代表任意一个字符,也就是这两个指针同时后移一位(或者是这两个字符相等)

2.当出现'*'的时候:

   (1)当s和p相等(注意这个相等),p+1是‘*’的时候,会出现三种情况:

                a.模式不变(也就是指针p不变),s向后移动一位。比如abbcd和ab*cf,其中s和p都指向了b。由于b出现了多次,应该不着急移动p,所以此时s+1即可。

                b.忽略这个‘*’,p向后移动两位,s向后移动一位。比如abcd和ab*cf,其中s和p都指向了b。此时应该s+1和p+2

                c.忽略这个'*’,p向后移动两位,s不变。比如"cba","cb*a*a",我也可以认为,p指向的第1个a没出现过,即使你相等。因此此时可以s不动,p+2(也就是直接跳到最后比较)。

 (2)当s和p不相等的时候,p+1是‘*’的情况,相当于这个没出现,p向后移动两位。

由于把真正的相等和'.'标记的相等并成一类,就只用考虑'*'。如果不出现星号,就常规比较,常规比较肯定出现相等或者不等两类。如果出现星号,就考虑两个指针指的是否相等,不等,则p指针直接+2。两个指针相等,则有3种情况并列处理。再在这些判断中,加入对应边界条件,就可以很容易理解并写出代码了。

public class Solution { public boolean match(char[] str, char[] pattern) { if(str==null || pattern==null){ return false; } return match(str,0,pattern,0); } public boolean match(char[] str,int s,char[] pattern,int p){ if(s==str.length && p==pattern.length){ return true; } if(s<str.length && p==pattern.length){ return false; } //下一个指针指向的是* if(p+1<pattern.length && pattern[p+1]=='*'){ //出现了*号,并且s和p指的相同 if((s<str.length && pattern[p]=='.') || (s<str.length && str[s]==pattern[p] )){ return match(str,s,pattern,p+2) || match(str,s+1,pattern,p+2) || match(str,s+1,pattern,p); } else{ return match(str,s,pattern,p+2); } } //下一个不是* if(s<str.length&& (str[s]==pattern[p] || pattern[p]=='.')){ return match(str,s+1,pattern,p+1); } return false; } }

 

 

最新回复(0)