forked from Silver-Taurus/algorithms_and_data_structures
-
Notifications
You must be signed in to change notification settings - Fork 0
/
wild_card_matching.cpp
84 lines (79 loc) · 2.34 KB
/
wild_card_matching.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/*
* Implement wildcard pattern maching with support for '?' & '*'
* '?' Matches any single character
* '*' Matches any sequence of character
* Source : Leetcode problem 44.
*
* Approach:
*
* Consider examples:
* is_match("aa", "a") false
* is_match("aa", "aaa") false
* is_match("aa", "?a") true
* is_match("aa", "?*") true
* is_match("aa", "*") true
* is_match("aa", "*a") true
* is_match("aa", "a*") true
* is_match("cabcab", "*ab") true
*
* Approach:
* Clearly, the '*' with multiple pattern matches makes this problem
* a little complicated, for example last case in the example.
* The second pattern of ab will give us the right answer.
* Therefore, we will have to try and match the same * with multiple
* patterns, and backtrack when we fail to match.
* For example:
* When we iterate source string and target pattern
* "cabcab" and "*ab" with i and j respectively, we will realize at
* i = 3 and j = 3 that we failed, at that time, we will have backtrack
* j back to position next to '*' i.e. j = 1, so that we can continue
* looking for further occurances of ab.
* Therefore, we will have to remember positions of '*' and reset
* iterator when we try to match the pattern.
*/
#include <iostream>
#include <string>
bool is_match(const std::string& str, const std::string& pattern)
{
int sLen = str.length();
int pLen = pattern.length();
int i = 0;
int j = 0;
int last_star_position = -1;
int last_match = -1;
while (i < sLen) {
if (j < pLen && (str[i] == pattern[j] ||
pattern[j] == '?')) {
++i;
++j;
}
else if (j < pLen && pattern[j] == '*') {
last_star_position = j;
last_match = i;
j++;
}
else if (last_star_position != -1) {
j = last_star_position + 1;
last_match++;
i = last_match;
}
else return false;
}
while (j < pLen && pattern[j] == '*') {
++j;
}
return j == pLen;
}
int main()
{
std::string str{"cabcab"};
std::string pattern{"*ab"};
if (is_match(str, pattern)) {
std::cout << "'" << str << "'"
<< " and '" << pattern << "'" << " are a match\n";
} else {
std::cout << "'" << str << "'"
<< " and '" << pattern << "'" << " are not a match\n";
}
return 0;
}