剑指Offer,面试题19,正则表达式匹配

面试题19

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


解析:本题用java写要考虑数组越界的问题,然后分为几种情况去讨论


首先说跳出递归的条件:

1. 当str和pattern都到了末尾,那就说明前面匹配成功,返回true

2. 当pattern已经到达末尾,而str没有匹配完,就说明str串长,匹配失败,返回false

3. 当str到达末尾,而pattern没有到达末尾

   1)判断pattern当前不为*并且后面也不是*的情况,遍历pattern后面的所有,如果有这种情况就返回false(因为str已经到末尾,就需要pattern后面的字符串与*相互抵消才可以匹配成功)

   2)否则后面字符串可以抵消,返回true


然后我们讨论边界的匹配情况:

就是判断当前pattern的位置的下一个到达串的末尾,那么如果当前的str与pattern相等或者pattern为.的话,就说明匹配成功,否则匹配失败

(这个放在前面说,是因为我们后面讨论的情况需要判断pattern当前位置的下一个是否为*,对其进行分类讨论)


最后讨论如何进行分类:

我们考虑pattern当前的下一个字符是否为*,对其进行分类讨论

1.下一个不为*,这种情况比较简单,只需要判断当前是否相等就可以

   1)如果当前pattern和str匹配(包括pattern为.的情况),则,pattern和str分别向下一个位置移动

   2)如果当前匹配不成功,则的返回false

2.pattern下一个字符为*(因为前面已经考虑下一个是否越界的情况,所以这里不需要考虑是否越界了)

那么也得进行分类讨论,就是当前字符是否匹配

    1)当前字符匹配成功(包括pattern为.的情况),那么也同样分为二种情况:

       (1)str向后移动一位,pattern不动(类似str=aaa,pattern=a*的情况,第一个a为当前位置)

       (2)str不动,pattern向后移动二位(类似str = ab ,pattern =a*ab的情况,第一个a为当前位置)

    2)当前字符匹配不成功,那么*表示的就相当于当前字符出现0次,所以str不动,pattern向后移动二位


import java.util.*;
public class N19 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine();
String p = in.nextLine();
char str[] = s.toCharArray();
char pattern[] = p.toCharArray();
if(str==null||pattern==null)
System.out.println("false");
System.out.println(String.valueOf(M(str,pattern,0,0)));
}
private static boolean M(char str[],char pattern[],int i,int j){
if(i==str.length&&j==pattern.length)
return true;
if(i!=str.length&&j==pattern.length)
return false;
if(i==str.length&&j!=pattern.length){//当i在字符串尾,j没在模式串尾,
while(j!=pattern.length){
if(pattern[j]!='*'&&(j+1>=pattern.length||pattern[j+1]!='*')){
                    return false;
                }
                j++;
}
return true;
}
if(j+1==pattern.length){ //判断边界
if(str[i]==pattern[j]||pattern[j]=='.')
return M(str,pattern,i+1,j+1);
else
return false;
}
if(pattern[j+1]!='*'&&(str[i]==pattern[j]||pattern[j]=='.'))
return M(str,pattern,i+1,j+1);
if(pattern[j+1]=='*'&&(str[i]==pattern[j]||pattern[j]=='.'))
return M(str,pattern,i+1,j)||M(str,pattern,i,j+2);
if(pattern[j+1]=='*'&&str[i]!=pattern[j])
return M(str,pattern,i,j+2);
return false;

}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值