C++算法:通配符匹配----双指针

题目:

给定一个字符串 (s) 和一个字符模式 § ,实现一个支持 ‘?’ 和 ‘*’ 的通配符匹配。

‘?’ 可以匹配任何单个字符。
‘*’ 可以匹配任意字符串(包括空字符串)。

两个字符串完全匹配才算匹配成功。

说明:

s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *。

示例 1:

输入:
s = “aa”
p = “a”
输出: false
解释: “a” 无法匹配 “aa” 整个字符串。

示例 2:

输入:
s = “aa”
p = ""
输出: true
解释: '
’ 可以匹配任意字符串。

示例 3:

输入:
s = “cb”
p = “?a”
输出: false
解释: ‘?’ 可以匹配 ‘c’, 但第二个 ‘a’ 无法匹配 ‘b’。

示例 4:

输入:
s = “adceb”
p = “ab”
输出: true
解释: 第一个 ‘’ 可以匹配空字符串, 第二个 '’ 可以匹配字符串 “dce”.

示例 5:

输入:
s = “acdcb”
p = “a*c?b”
输入: false

思路一:

双指针法:每次遇到就记录此时的两个位置,首先将忽略继续查找,当不匹配后回到记录的位置的下一个位置,并将记录对应s串中的位置+1,以备下次失配时,回来*匹配多个字符

思路二:

递归回溯法:思想类似于正则匹配,但是此方法只能通过一半的例子

代码:

#if 1
//双指针法:每次遇到*就记录此时的两个位置,首先将*忽略继续查找,当不匹配后回到记录*的位置的下一个位置,并将记录*对应s串中的位置+1,以备下次失配时,回来*匹配多个字符
vector<vector<bool>> memo_bool;
//要考虑多个*的情况
class Solution {
public:
    bool isMatch(string s, string p) {
        int i = 0, j = 0, match = -1, s_start = -1;
        
        while(i < s.length())
        {
            if(j < p.length() && (p[j] == s[i] || p[j] == '?'))
            {
                i++;
                j++;
            }
            else if(j < p.length() && (p[j] == '*'))
            {
                match = j;
                s_start = i;
                j++;
            }
            else if(match != -1)
            {
                j = match + 1;
                i = s_start + 1;
                s_start += 1;
            }
            else
                return false;
        }
        while(j < p.length() && p[j] == '*')
            j++;
        if(j == p.length())
            return true;
        else
            return false;
    }
};
#endif


#if 0
//递归回溯法:思想类似于正则匹配,但是此方法只能通过一半的例子
vector<vector<bool>> memo_bool;
//要考虑多个*的情况
class Solution {
public:
    bool isMatch(string s, string p) {
        vector<vector<bool>> temp(s.size()+1,vector<bool>(p.size()+1, NULL));
        memo_bool = temp;
        temp.clear();
       return matchSub(s, p, 0, 0);
    }
    
private:
    bool matchSub(string& s, string& p, int i, int j){
        //终止条件
        if(memo_bool[i][j] != NULL)
            return memo_bool[i][j];
        
        bool ans;
        
         if(s.length() == i)
        {
            if(p.length() == j)
                ans = true;
            int k;
            for(k = j; k < p.length(); k++)
                if(p[k] != '*')
                    break;
            if(k == p.length())
                ans = true;
            else 
                ans = false;
        }    
            
        else if(p.length() == j)
            ans = false;
        
        else if((p[j] == s[i]) || (p[j] == '?'))
           ans = matchSub(s, p, i+1, j+1);
        
        else
        {
            if(p[j] == '*')
            {
                while(j+1<p.length() && p[j+1] == p[j])
                    j++;
                ans = matchSub(s, p, i+1, j) || matchSub(s, p, i+1, j+1) || matchSub(s, p, i, j+1);
            }
            else
                ans = false;
        }
        
        memo_bool[i][j] = ans;
        return ans;
    }
};
#endif

猜你喜欢

转载自blog.csdn.net/qq_31820761/article/details/91862239