/** * @param {string} s * @param {string} p * @return {boolean} */ var isMatch = function (s, p) { if (s == null || p == null) return false;//极端情况 s和p都是空 返回false const sLen = s.length, pLen = p.length; const dp = new Array(sLen + 1);//因为位置是从0开始的,第0个位置是空字符串 所以初始化长度是sLen + 1 for (let i = 0; i < dp.length; i++) {//初始化dp数组 dp[i] = new Array(pLen + 1).fill(false); // 将项默认为false } // base case s和p第0个位置是匹配的 dp[0][0] = true; for (let j = 1; j < pLen + 1; j++) {//初始化dp的第一列,此时s的位置是0 //情况1:如果p的第j-1个位置是*,则j的状态等于j-2的状态 //例如:s='' p='a*' 相当于p向前看2个位置如果匹配,则*相当于重复0个字符 if (p[j - 1] == "*") dp[0][j] = dp[0][j - 2]; } // 迭代 for (let i = 1; i < sLen + 1; i++) { for (let j = 1; j < pLen + 1; j++) { //情况2:如果s和p当前字符是相等的 或者p当前位置是. 则当前的dp[i][j] 可由dp[i - 1][j - 1]转移过来 //当前位置相匹配,则s和p都向前看一位 如果前面所有字符相匹配 则当前位置前面的所有字符也匹配 //例如:s='XXXa' p='XXX.' 或者 s='XXXa' p='XXXa' if (s[i - 1] == p[j - 1] || p[j - 1] == ".") { dp[i][j] = dp[i - 1][j - 1]; } else if (p[j - 1] == "*") {//情况3:进入当前字符不匹配的分支 如果当前p是* 则有可能会匹配 //s当前位置和p前一个位置相同 或者p前一个位置等于. 则有三种可能 //其中一种情况能匹配 则当前位置的状态也能匹配 //dp[i][j - 2]:p向前看2个位置,相当于*重复了0次, //dp[i][j - 1]:p向前看1个位置,相当于*重复了1次 //dp[i - 1][j]:s向前看一个位置,相当于*重复了n次 //例如 s='XXXa' p='XXXa*' if (s[i - 1] == p[j - 2] || p[j - 2] == ".") { dp[i][j] = dp[i][j - 2] || dp[i][j - 1] || dp[i - 1][j]; } else { //情况4:s当前位置和p前2个位置不匹配,则相当于*重复了0次 //例如 s='XXXb' p='XXXa*' 当前位置的状态和p向前看2个位置的状态相同 dp[i][j] = dp[i][j - 2]; } } } } return dp[sLen][pLen]; // 长为sLen的s串 是否匹配 长为pLen的p串 };
标签:10,匹配,正则表达式,sLen,位置,pLen,XXXa,dp From: https://www.cnblogs.com/yadayou/p/17849751.html