网页设计专业学校优化网站排名如何
web/
2025/10/8 3:03:03/
文章来源:
网页设计专业学校,优化网站排名如何,一级域名跳转到二级域名,做壁纸网站的意义乘风破浪#xff1a;LeetCode真题_010_Regular Expression Matching 一、前言 关于正则表达式我们使用得非常多#xff0c;但是如果让我们自己写一个#xff0c;却是有非常大的困难的#xff0c;我们可能想到状态机#xff0c;确定#xff0c;非确定状态机确实是一种解决…乘风破浪LeetCode真题_010_Regular Expression Matching 一、前言 关于正则表达式我们使用得非常多但是如果让我们自己写一个却是有非常大的困难的我们可能想到状态机确定非确定状态机确实是一种解决方法不过需要消耗很大的时间去推理和计算对于正则表达式的缩小版我们往往可以通过递归递推动态规划等方法来解决。 二、Regular Expression Matching 2.1 问题理解 2.2 问题分析和解决 遇到这样的问题我们想到了递归对于.是很好处理和匹配的但是如果和*结合起来就变化无穷了正是因为*我们才要递归。 让我们看看官方的答案 class Solution {public boolean isMatch(String text, String pattern) {if (pattern.isEmpty()) return text.isEmpty();boolean first_match (!text.isEmpty() (pattern.charAt(0) text.charAt(0) || pattern.charAt(0) .));if (pattern.length() 2 pattern.charAt(1) *){return (isMatch(text, pattern.substring(2)) ||(first_match isMatch(text.substring(1), pattern)));} else {return first_match isMatch(text.substring(1), pattern.substring(1));}}
}如果模式串和源串第一个字符能够正常匹配并且不为空模式串的第二个字符不为*那么我们可以继续递归匹配下面的东西 1 return first_match isMatch(text.substring(1), pattern.substring(1)); 如果模式串的长度大于1并且第二个字符是*,那么我们就有可能匹配到源串的很多的字符也就相当于将源串已经匹配的去掉拿剩下的和整个模式串继续比较此时*发挥了作用或者比较源串与去掉了*的模式串因为*没有能够发挥作用。于是就得到了 1 if (pattern.length() 2 pattern.charAt(1) *){
2 return (isMatch(text, pattern.substring(2)) ||
3 (first_match isMatch(text.substring(1), pattern)));
4 } 除此之外我们还可以使用动态规划算法 class Solution {public boolean isMatch(String text, String pattern) {boolean[][] dp new boolean[text.length() 1][pattern.length() 1];dp[text.length()][pattern.length()] true;for (int i text.length(); i 0; i--){for (int j pattern.length() - 1; j 0; j--){boolean first_match (i text.length() (pattern.charAt(j) text.charAt(i) ||pattern.charAt(j) .));if (j 1 pattern.length() pattern.charAt(j1) *){dp[i][j] dp[i][j2] || first_match dp[i1][j];} else {dp[i][j] first_match dp[i1][j1];}}}return dp[0][0];}
}首先我们定义dp[i][j]代表源串T[i:]和模式串P[j:]是匹配的其中i,j为源串和模式串的下标于是我们只要求得dp[0][0]的值就可以了。我们已知的条件是 dp[text.length()][pattern.length()] true; 于是我们从后往前倒求最终的dp[0][0]通过如下的判断看看是哪一种情况然后根据相应的情况采取不同的递推策略最终得到结果 1 boolean first_match (i text.length()
2 (pattern.charAt(j) text.charAt(i) ||
3 pattern.charAt(j) .));
4 if (j 1 pattern.length() pattern.charAt(j1) *){
5 dp[i][j] dp[i][j2] || first_match dp[i1][j];
6 } else {
7 dp[i][j] first_match dp[i1][j1];
8 } 同样的我们算法也是使用了递归和动态规划 在动态规划方面我们使用match[i]来表示对于源串从i到最后T[i:]都是能够匹配的于是之用求match[0]即可。 import java.util.Arrays;public class Solution {/*** Implement regular expression matching with support for . and *.* . Matches any single character.* * Matches zero or more of the preceding element.** 题目大意* 实现一个正则表达式匹配算法.匹配任意一个字符*匹配0个或者多个前导字符*/public boolean isMatch(String s, String p) {boolean[] match new boolean[s.length() 1]; Arrays.fill(match, false);match[s.length()] true;//刚开始满足需要for (int i p.length() - 1; i 0; i--) {if (p.charAt(i) *) {for (int j s.length() - 1; j 0; j--) { //原来就是false只有能够为真才为真。match[j] match[j] || match[j 1] (p.charAt(i - 1) . || s.charAt(j) p.charAt(i - 1));}i--;} else {for (int j 0; j s.length(); j) { //从前往后只有到了已经有true的时候才能生效。如果从后往前反而有问题。 match[j] match[j 1] (p.charAt(i) . || p.charAt(i) s.charAt(j));}//将最后的置为假本来就应该不真便于以后的判断match[s.length()] false;}}return match[0];}// 下面的代码用时比较长public boolean isMatch2(String s, String p) {// 输入都为nullif (s null p null) {return true;}// 有一个为nullelse if (s null || p null) {return false;}return isMatch(s, 0, p, 0);}/*** 正则表达式匹配** param s 匹配串* param sIdx 当前匹配的位置* param p 模式串* param pIdx 模式串的匹配位置* return 匹配结果*/public boolean isMatch(String s, int sIdx, String p, int pIdx) {// 同时到各自的末尾if (s.length() sIdx p.length() pIdx) {return true;}// 当匹配串没有到达末尾模式串已经到了末尾else if (s.length() ! sIdx p.length() pIdx) {return false;}// 其它情况else {// 如果当前匹配的下一个字符是*号if (pIdx p.length() - 1 p.charAt(pIdx 1) *) {// 匹配串未结束并且当前字符匹配字符相等或者是.号if (sIdx s.length() (s.charAt(sIdx) p.charAt(pIdx) || p.charAt(pIdx) .)) {return isMatch(s, sIdx 1, p, pIdx 2) // 匹配串向前移动一个字符只匹配一次|| isMatch(s, sIdx 1, p, pIdx) // 匹配串向前移动一个字符下一次匹配同样的模式串不动|| isMatch(s, sIdx, p, pIdx 2); // 忽略匹配的模式串} else {// 忽略*return isMatch(s, sIdx, p, pIdx 2);}}// 匹配一个字符if (sIdx s.length() (s.charAt(sIdx) p.charAt(pIdx) || p.charAt(pIdx) .)) {return isMatch(s, sIdx 1, p, pIdx 1);}}return false;}}如下表所示使用递归需要1163ms而使用动态规划需要20ms差别非常显著。 三、总结 对于一些比较困难的问题我们需要从不同的角度考虑解决问题的方法可以从递归递推动态规划等方面去考虑。转载于:https://www.cnblogs.com/zyrblog/p/10211390.html
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/88837.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!