【题目】
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,判断模式串p和字符串s是否匹配
"?"能匹配任意单个字符串
"*"能匹配一个任意长度的字符串,包括空串
【思路】
关键在于确定每个*匹配的字符串长度。
如果出现连续的*, 我们只需要考虑最后一个*, 前面几个*没有任何影响。
*匹配长度的选择遵从:恰好接手原则。即下一个*接手上一个*继续往下匹配可能有多种情况出现。我们选择刚好能接手的第一种情况。
举个例子来说:
index: 0 1 2 3 4 5 6 7
s: a b a d c b a c
p: *ba*ac
第二个*接手第一个*继续匹配有两种情况:
1. 第一个*匹配到s[0], 后继的s[1-2]正好能匹配ba,之后第二个*从s[3]开始接手,继续往下匹配
2. 第一个*匹配到s[4], 后继的s[5-6]正好能匹配ba,之后第二个*从s[7]开始接手,继续往下匹配
则按照上面提到的“恰好接手”的原则,我们选择第1种情况。
如果过度贪心,则会导致模式串中的后续字符串可能得不到匹配,例如,如果第一个*选择第2种匹配策略,模式串p的后缀ac就无法得到匹配。
【代码】
class Solution { public: bool isMatch(const char *s, const char *p) { const char *sStart="\0"; const char *pStart="\0"; while(*s){ if(*p=='*'){ while(*p=='*')p++; if(*p=='\0')return true; sStart=s; pStart=p; } else if(*p=='?'){ s++;p++; } else if(*p!='\0'){ if(*s==*p){ s++;p++; } else{ //如果对应位置上的字符不匹配 //则我们认为和p当前字符匹配的字符还在被匹配串的后边位置,则最近的那个*需要再多匹配一些字符。 //因此需要回溯,并增加*匹配的字符数,一般就+1 //如果发现前面没有出现过*, 也就无法回溯,只能认命匹配不了,返回false if(!*sStart || !*pStart)return false; s=++sStart; p=pStart; } } else{ //如果模式串已经结束了,但是被匹配串的还没匹配完。 //则,我们需要考虑最近的那个*需要再多匹配一些字符。 //因此需要回溯,并增加*匹配的字符数,一般就+1 //如果发现前面没有出现过*, 也就无法回溯,只能认命匹配不了,返回false if(!*sStart || !*pStart)return false; s=++sStart; p=pStart; } } //别忘了模式串最后可能还剩点尾巴 while(*p){ if(*p!='*')return false; p++; } return true; } };
LeetCode: Wildcard Matching [043],布布扣,bubuko.com
时间: 2024-08-08 13:49:59