通配符匹配-LintCode

204 篇文章 0 订阅

判断两个可能包含通配符“?”和“*”的字符串是否匹配。匹配规则如下:

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

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

函数接口如下:
bool isMatch(const char *s, const char *p)

样例
一些例子:

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是否匹配。给定位置m,n,
若p[n]是字母,若s[m]==p[n],处理m+1和n+1位置,否则返回false;
若p[n]=’?’,可以匹配任一单个字符,直接处理m+1和n+1位置;
若p[n]=’*’,匹配0个或多个字符,处理j和n+1位置(m<=j<=s.size()),
有满则条件的情况则返回true,否则返回false。
为了减少计算量,将对于m,n位置的处理结果存入到map中。

#ifndef C192_H
#define C192_H
#include<iostream>
#include<string>
#include<map>
using namespace std;
class Solution {
public:
    /*
    * @param s: A string
    * @param p: A string includes "?" and "*"
    * @return: is Match?
    */
    bool isMatch(string &s, string &p) {
        // write your code here
        map<pair<int, int>, bool> map;//利用map存放计算过的数据,减少运算量
        return helper(s, p, 0, 0,map);
    }
    bool helper(string &s, string &p, int m, int n,map<pair<int,int>,bool> &map)
    {
        pair<int, int> pairVal = make_pair(m, n);
        if (map.find(pairVal) != map.end())
            return map[pairVal];
        if (m >= s.size() && n == p.size())//设定终止条件
            return true;
        else if (m < s.size() && n < p.size())
        {
            if (isalpha(p[n]))            //p中元素为字母的情况,直接判断与s[m]是否相等
            {
                if (p[n] == s[m])
                    return helper(s, p, m + 1, n + 1,map);
                else
                {
                    map[pairVal] = false;
                    return false;
                }
            }
            else if (p[n] == '?')         //p中元素为'?',可以匹配任一单个字符,直接处理下一位
                return helper(s, p, m + 1, n + 1,map);
            else                          //p中元素为'*',循环判断是否存在满足条件的情况
            {
                bool flag = false;
                for (int i = m; i <= s.size(); ++i)
                {
                    flag = flag || helper(s, p, i, n + 1,map);
                }
                map[pairVal] = flag;
                return flag;
            }
        }          
        //此时p[n]只能为'*'
        else if (m >= s.size() && n < p.size())
        {
            for (int j = n; j < p.size(); ++j)
            {
                if (p[j] != '*')
                    return false;
            }
            return true;
        }
        else
            return false;
    }
};
#endif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值