您的位置:首页 > Web前端

剑指offer(55):正则表达式匹配

2016-04-29 18:43 239 查看
题目描述

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

分析

思路来源于剑指offer书籍,理解的还不是很透彻。

每次从字符串里拿出一个字符和模式中的字符去匹配。如果模式中的字符ch是’.’,那么它可以匹配字符串中的任意字符。如果模式中的字符ch不是’.’,而字符串中的字符也是ch,则它们同样相互匹配,接着匹配后面的字符。

当模式中的第二个字符不是’*’时,比较简单。如果字符串中的第一个字符和模式中的第一个字符相匹配,那么字符串和模式上都向后移动一个字符,然后匹配剩余的字符串和模式。如果字符串中的第一个字符和模式中的第一个字符不匹配,则直接返回false。

当模式中的第二个字符是’*’,比较复杂,可能有多种匹配方法。一个选择是在模式上向后移动两个字符。这相当于’*’和它前面的字符被忽略掉了,因为’*’可以匹配字符串中的0个字符。如果模式中的第一个字符和字符串中的第一个字符相匹配时,则在字符串向后移动一个字符,而在模式上有两个选择:向后移动两个字符,或者保持模式不变。



模式ba*ab的非确定有限状态机。当匹配进入状态2并且字符串的字符是’a’时,有两个选择:进入状态3,或者回到状态2。

当匹配进入状态2并且字符串的字符是’a’时,有两个选择:进入状态3(在模式上向后移动两个字符),或者回到状态2(模式保持不变)。

牛客AC:

package com.problem;

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

public boolean match(char[] str, char[] pattern) {
return isMatch(str, 0, pattern, 0);
}

public boolean isMatch(char[] str, int strIndex, char[] pattern, int patternIndex) {
if (strIndex == str.length && patternIndex == pattern.length)   // 同时结束
return true;
if (patternIndex >= pattern.length)     // pattern 先结束
return false;
if (strIndex == str.length)     // str结束
return false;

// patternIndex 还没到达倒数第二位
if (patternIndex < pattern.length - 1) {
// 如果下一位是 *
if (pattern[patternIndex + 1] == '*') {
if ((strIndex < str.length) &&
(str[strIndex] == pattern[patternIndex] || pattern[patternIndex] == '.')) {
// 第一种,模式上移动两个字符,相当于忽略‘*’和它前面的字符
return isMatch(str, strIndex, pattern, patternIndex + 2) ||
// 第二种,当前字符匹配成功,模式上移动两个字符
isMatch(str, strIndex + 1, pattern, patternIndex + 2) ||
// 第三种,当前字符匹配成功,模式上保持不变
isMatch(str, strIndex + 1, pattern, patternIndex);
} else
// 忽略'*'和它前面的字符
return isMatch(str, strIndex, pattern, patternIndex + 2);
}
}

// 下一位不是‘*’,则只要匹配'.',匹配成功后,同时移动一个字符
if (str[strIndex] == pattern[patternIndex] || pattern[patternIndex] == '.')
return isMatch(str, strIndex + 1, pattern, patternIndex + 1);

return false;
}
}


参考

1. 何海涛,剑指offer名企面试官精讲典型编程题(纪念版),电子工业出版社
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: