Java 中的正则表达式匹配

实现支持“。”的正则表达式匹配 和“ *”。

‘。’ 匹配任何单个字符。
'*'匹配零个或多个前一个元素。
匹配项应覆盖整个输入字符串(而非部分)。

函数原型应该是:
bool isMatch(const char * s,const char * p)
一些示例:
isMatch(“ aa”,“ a”)返回false
isMatch(“ aa”,“ aa”)返回true
isMatch(“ aaa”,“ aa”)返回false
isMatch(“ aa”,“ a ”)返回true
isMatch(“ aa”,“。
”)返回true
isMatch(“ ab”,“。*”)返回true
isMatch(“ aab”,“ c * a * b”)返回true

1.分析

首先,这是最困难的问题之一。很难考虑所有不同的情况。该问题应简化为处理2种基本情况:

模式的第二个字符为“ *”
模式的第二个字符不是“ *”
对于第一种情况,如果pattern的第一个字符不是“。”,则pattern和string的第一个字符应相同。然后继续匹配其余部分。

对于第二种情况,如果模式的第一个字符为“。” 或pattern的第一个字符==字符串的第一个i字符,继续匹配其余部分。

2. Java解决方案1(简短)

接受以下Java解决方案。

public class Solution {
    public boolean isMatch(String s, String p) {
 
        if(p.length() == 0)
            return s.length() == 0;
 
        //普的长度1是特殊情况    
        if(p.length() == 1 || p.charAt(1) != '*'){
            if(s.length() < 1 || (p.charAt(0) != '.' && s.charAt(0) != p.charAt(0)))
                return false;
            return isMatch(s.substring(1), p.substring(1));    
 
        }else{
            int len = s.length();
 
            int i = -1; 
            while(i<len && (i < 0 || p.charAt(0) == '.' || p.charAt(0) == s.charAt(i))){
                if(isMatch(s.substring(i+1), p.substring(2)))
                    return true;
                i++;
            }
            return false;
        } 
    }
}

3. Java解决方案2(更易读)

public boolean isMatch(String s, String p) {
	//基本情况
	if (p.length() == 0) {
		return s.length() == 0;
	}
 
	//特例
	if (p.length() == 1) {
 
		//如果s的长度为0,则返回false
		if (s.length() < 1) {
			return false;
		}
 
		//如果第一个不匹配,返回false 
		else if ((p.charAt(0) != s.charAt(0)) && (p.charAt(0) != '.')) {
			return false;
		}
 
		//否则,比较s和p的其余字符串。
		else {
			return isMatch(s.substring(1), p.substring(1));
		}
	}
 
	//情况1:当p的第二个字符不是'*' 
	if (p.charAt(1) != '*') {
		if (s.length() < 1) {
			return false;
		}
		if ((p.charAt(0) != s.charAt(0)) && (p.charAt(0) != '.')) {
			return false;
		} else {
			return isMatch(s.substring(1), p.substring(1));
		}
	}
 
	//情况2:当p的第二个字符为'*'时,为复杂情况。
	else {
		///壳体2.1:一个char& '*'可以代表0元件
		if (isMatch(s, p.substring(2))) {
			return true;
		}
 
		//情况2.2:char&'*'可以代表1个或多个前面的元素,
		//因此请尝试每个子字符串
		int i = 0;
		while (i<s.length() && (s.charAt(i)==p.charAt(0) || p.charAt(0)=='.')){
			if (isMatch(s.substring(i + 1), p.substring(2))) {
				return true;
			}
			i++;
		}
		return false;
	}
}

Java解决方案3-使用索引
我们还可以添加一个辅助方法来使用索引,而不是递归地传递子字符串。

public boolean isMatch(String s, String p) {
    return helper(s, p, 0, 0);
}
 
private boolean helper(String s, String p, int i, int j) {
    if (i >= s.length() && j >= p.length()) {
        return true;
    }
 
 
    if (j < p.length() - 1 && p.charAt(j + 1) == '*') {
        if (helper(s, p, i, j + 2)) {
            return true;
        }
 
        if (p.charAt(j) == '.') {
            for (int k = i; k < s.length(); k++) {
                if (helper(s, p, k + 1, j + 2)) {
                    return true;
                }
            }
        } else {
            for (int k = i; k < s.length(); k++) {
                if (s.charAt(k) == p.charAt(j)) {
                    if (helper(s, p, k + 1, j + 2)) {
                        return true;
                    }
                } else {
                    break;
                }
            }
        }
    } else if (i < s.length() && j < p.length() && (s.charAt(i) == p.charAt(j) || p.charAt(j) == '.')) {
        return helper(s, p, i + 1, j + 1);
    }
 
    return false;
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值