标签:
Implement wildcard pattern matching with support for ‘?‘ and ‘*‘.
‘?‘ Matches any single character. ‘*‘ Matches any sequence of characters (including the empty sequence). The matching should cover the entire input string (not partial). The function prototype should be: bool isMatch(const char *s, const char *p) Some examples: isMatch("aa","a") → false isMatch("aa","aa") → true isMatch("aaa","aa") → false isMatch("aa", "*") → true isMatch("aa", "a*") → true isMatch("ab", "?*") → true isMatch("aab", "c*a*b") → false
实现通配符,支持‘?‘和’*’。‘?‘匹配任意单个字符,’*’匹配任意字符串序列,包含空字符。匹配整个字符串,而不是部分。
之前做过正则表达式的匹配,与通配符非常类似,不同的是对‘*‘的处理,通配符中用来匹配任意字符序列而不是某个字符的重复。
假设 S 是要匹配的字符串,P 是模式串。还是用DP来解决,设计函数F(i,j)表示S.substr(0, i) 和P.substr(0, j)是否匹配,令M = S.size(),N = P.size(),那么 i ∈ [0, M],j ∈ [0, N],递推公式是 F(i,j) = { P[j]==‘*‘ && (F(i,j-1) || F(i-1,j) } || { (P[j]==‘?‘ || S[i]==P[j]) && F(i-1, j-1) }。左半段表示当P[j]等于‘*‘字符时,有两种情况,一种是F(i,j-1)表示‘*‘匹配零个字符,另一种F(i-1,j)表示匹配一到多个字符;右半段表示当P[j]等于‘?‘或其他字符时,需要检测S[i]和P[j]是否匹配,然后再用F(i-1, j-1)判断之前的串是否匹配。如此,需要计算M*N个状态,如果要存储所有状态,空间复杂度就是是O(M*N),时间复杂度也是O(M*N),不过实际上递推式只用到了相邻的状态,所以可以将二维的空间压缩到一维,例如,可以使用数组R[i]存储S.substr(0,i)与P.substr(0,j)是否匹配,具体做法是:先初始化 j=0, R[0] = true, R[j] = false (j ∈ [1, M]),然后将 j 从 1 迭代到 N ,每次迭代重新计算一次 R ,计算的时候当然会用到上一次的R,最后R[M]就是结果。代码如下:
bool isMatch(string s, string p) { vector<bool> bM(s.size()+1, false); bM[0] = true; for (int j=0; j<p.size(); ++j) { bool last = bM[0]; if (p[j] != ‘*‘) bM[0] = false; for (int i=0; i<s.size(); ++i) { bool tmp = bM[i+1]; if (‘*‘ == p[j]) bM[i+1] = bM[i] || bM[i+1]; else bM[i+1] = (‘?‘ == p[j] || s[i]==p[j]) && last; last = tmp; } } return bM.back(); }
标签:
原文地址:http://www.cnblogs.com/zhiguoxu/p/5474876.html