一、介绍
进行字符串的匹配,在第一个字符串s中,都是正儿八经的字符。而在第二个字符串中,有 . 还有 * 这样的匹配符号。其中, . 可以替代任意一个字符,*可以让它前面出现的那个字符出现0~n次,如果前是 . 的话,那就是代表任意个.了。因此,题目中给出两个字符串s和p,判断是否可以相同。题目链接如下:https://leetcode.com/problems/regular-expression-matching/
二、思路
首先,我们编写几个函数,第一个函数canMatch(String s, String p, int i, int j),用来查看两个字符s中i位置和p中j位置的字符是否可以匹配,例如a可以匹配a,a也可以匹配 . 这两种情况;
之后,第二个函数canMatch2(String p, int index2)。因为当s中的字符遍历完之后,p的末尾可能还有z*b*c*这样的字符串,而且因为*可以使前面的元素出现次数为0,所以它们刚好可以去匹配null。
接着,我们实现主要的函数helper(String s, String p, int index1, int index2),用来比较s中从index1开始,p中从index2开始之后的字符串是否可以完全匹配。其中分情况考虑:
- 如果两个字符串都匹配结束了,那么就成功了;如果仅仅是s匹配完了,那么就由q调用canMatch2函数。如果也是true,那么就成功了;否则失败。如果仅仅q遍历完了,肯定是不成功了。
- 而如果都没有遍历完,那就需要先看p中的index2对应的字符和它后面的字符是不是像a*这样的,因为这种情况下,a可以出现0次或者很多次。当然,如果第一个字符就不能和s中的index1对应的字符相匹配的话,那么index2对应的那个字符肯定只能出现0次了;否则就既要考虑出现0次,也要考虑出现n次。
- 最后呢?如果没有p中后面出现a*这样的情况,就要看index1和index2分别对应的字符是否相等,相等的话,就各自前进一步继续递归判断,否则连它们都当前字符都匹配不了,就代表失败。
三、代码
//字符串的匹配,对应字符可以匹配;.可以匹配任意一个字符;*可以让它前面的那个元素的出现次数从0到无穷。
class Solution {
public boolean isMatch(String s, String p) {
return helper(s, p, 0, 0);
}
public boolean helper(String s, String p, int index1, int index2){
boolean res1 = (index1 == s.length());
boolean res2 = (index2 == p.length());
boolean res3 = (index2 + 2 == p.length() && p.charAt(index2 + 1) == '*'); //最后只剩下类似a*这样的两个字符了
if(res1 && (res2 || res3))
return true;
if(res1 || res2){
if(res1)
return canMatch2(p, index2); //看看后面是不是都是z*b*c*这样的
else
return false;
}
//p的后面是那种a*的情况,这样a既可能出现0次,也可能出现多次
if(index2+1 < p.length() && p.charAt(index2+1) == '*'){
if(canMatch(s, p, index1, index2))
return helper(s, p, index1, index2+2) || helper(s, p, index1+1, index2); //出现0次或者很多次
else
return helper(s, p, index1, index2+2); //不相等,必然只能出现0次
}
//最后一种情况,当前仅仅是有能够匹配的单个字符
if(canMatch(s, p, index1, index2))
return helper(s, p, index1+1, index2+1);
return false;
}
//查看两个字符是否可以匹配
public boolean canMatch(String s, String p, int i, int j){
if(s.charAt(i) == p.charAt(j) || p.charAt(j) == '.')
return true;
else
return false;
}
//判断p末尾是不是都是a*b*c*这样的结构
public boolean canMatch2(String p, int index2){
for(int i = index2;i < p.length();){
if(i+1 < p.length() && p.charAt(i+1) == '*')
i += 2;
else
return false;
}
return true;
}
}