每日算法之三十五:Wildcard Matching

模式匹配的实现,‘?‘代表单一字符,‘*‘代表任意多的字符,写代码实现两个字符串是否匹配。

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

要注意的就是‘*‘可以代表任意长度的字符,甚至可以是0个。也就是可以忽略。下面是简单的分析思路:

1)两个辅助指针分别指向模式串和比较字符串,如果当前两个字符相等(可能是‘?‘),两个指针都加一比较下一个字符。

2)如果比较字符串当前字符是星号,因为星号可能代表0个字符或者多个字符,零个字符就代表比较字符串的下一个字符和模式串的当前字符比较,如果不相等,说明不是代表零个字符,这个时候就要用比较字符串的下一个跟模式串的下一个比较。如果相等说明可能代表零个字符,那么就等于执行了第一步。直到遇到不相等的字符时,说明星号可能代表了较多的字符,而我们只是吃掉了较少的字符,这个时候我们就应该回退到星号的后一个字符,去跟模式串之前标记不相等的位置的后一个去比较。因此,在遇到星号的时候我们应该标记模式串和比较字符串的位置,当遇到不相等的时候模式串的标记后移一位,说明星号多代表了一个字符。

3)最后比较字符串可能还剩下比较多的星号,应为星号可能代表零个字符,一次要忽略掉这些。

4)最后查看比较字符串是否到尾部就说明两个字符串是否匹配。

代码如下:

class Solution {
public:
    bool isMatch(const char *s, const char *p) {
        const char* star = nullptr;
        const char* rs = nullptr;

        while(*s) {
            if(*s == *p || *p == '?') { //match
                s++; p++;
                continue;
            }
            if(*p == '*') {
                star = p; // record star
                p++; //match from next p
                rs = s; // record the position of s , star match 0,从匹配零个字符开始
                continue;
            }
            if(star != nullptr) { //if have star in front then backtrace
                p = star + 1; //reset the position of p
                s = rs + 1;
                rs ++; //star match 1,2,3,4,5....每次都多吃掉一个字符
                continue;
            }
            return false; //if not match return false,能执行到这步说明发生了不匹配
        }
        while(*p == '*') p++; //skip continue star
        return *p == '\0'; // successful match,之前s已到结尾,看p是否遍历完代表是否匹配
    }
};

这与之前的一个例题有相似的地方,但是那里的星号是代表了前缀字符,而这里的星号可能代表任意字符数量。

这里的回退与KMP有相似的地方,两者能否比较融合呢?下次再看到这里的时候要做下比较。

每日算法之三十五:Wildcard Matching

时间: 2024-10-10 12:12:34

每日算法之三十五:Wildcard Matching的相关文章

每日算法之三十四:Multiply Strings

大数相乘,分别都是用字符串表示的两个大数,求相乘之后的结果表示. 首先我们应该考虑一下测试用例会有哪些,先准备测试用例对防御性编程会有比较大的帮助,能够考虑一些极端情况.有以下几种用例: 1)"0","0" 2)"0","879127346783" 其中一个是零 3)"as234","123343"  存在非法字符 4)"000000000000001234",&qu

每日算法之三十:Valid Sudoku (九宫格)

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump

每日算法之十五:threesumClosset

Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. For example, given array S = {-1 2

每日算法之三十九:Pow(x, n)

实现浮点类型的幂运算,函数原型为: double pow(double x, int n) 在求解这个问题的时候是一个很挣扎的过程,因为它不是报错而是一直提示你超出时间,那么必须一次次的考虑怎样降低时间复杂度. 首先最直接的思路是下面这样的,就跟直观的数学求解一样. double pow(double x, int n) { if(n==0) return 1.0; if(n<0) return 1.0/pow(x,-n); return x*pow(x,n-1); } 但是会提示你超出时间,这

每日算法之三十八:Anagrams

Given an array of strings, return all groups of strings that are anagrams. Note: All inputs will be in lower-case. 回文字符串是指: 两个字符串的字符个数完全相同,这两个字符串是Anagrams.因此Anagrams至少指俩字符串.找出字符集合中的Anagrams组. 由此我们可以想到,只要将几个单词按照字母顺序进行排序,就可以通过比较判断他们是否是anagrams. 思路:用map

经典算法题每日演练——第二十五题 块状链表

原文:经典算法题每日演练--第二十五题 块状链表 在数据结构的世界里,我们会认识各种各样的数据结构,每一种数据结构都能解决相应领域的问题,每一种数据结构都像 是降龙十八掌中的某一掌,掌掌毙命... 当然每个数据结构,有他的优点,必然就有它的缺点,那么如何创造一种数据结构 来将某两种数据结构进行扬长避短,那就非常完美了.这样的数据结构也有很多,比如:双端队列,还有就是今天讲的 块状链表, 我们都知道 数组 具有 O(1)的查询时间,O(N)的删除,O(N)的插入... 链表 具有 O(N)的查询时

经典算法题每日演练——第十五题 并查集

原文:经典算法题每日演练--第十五题 并查集 这一篇我们看看经典又神奇的并查集,顾名思义就是并起来查,可用于处理一些不相交集合的秒杀. 一:场景 有时候我们会遇到这样的场景,比如:M={1,4,6,8},N={2,4,5,7},我的需求就是判断{1,2}是否属于同一个集合,当然实现方法 有很多,一般情况下,普通青年会做出O(MN)的复杂度,那么有没有更轻量级的复杂度呢?嘿嘿,并查集就是用来解决这个问题的. 二:操作 从名字可以出来,并查集其实只有两种操作,并(Union)和查(Find),并查集

每日算法之四十二:Permutation Sequence (顺序排列第k个序列)

The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the permutations in order, We get the following sequence (ie, for n = 3): "123" "132" "213" "231" "312" "

每日算法之四十:Insert Interval

Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). You may assume that the intervals were initially sorted according to their start times. Example 1: Given intervals [1,3],[6,9], insert and merge