-
-
Notifications
You must be signed in to change notification settings - Fork 7.3k
/
wildcard_matching.cpp
156 lines (141 loc) · 5.04 KB
/
wildcard_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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/**
* @file
* @brief Implementation of the [Wildcard
* Matching](https://www.geeksforgeeks.org/wildcard-pattern-matching/) problem.
* @details
* Given a matching string and a pattern, 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 matching string (not partial). The task
* is to determine if the pattern matches with the matching string
* @author [Swastika Gupta](https://github.com/Swastyy)
*/
#include <cassert> /// for assert
#include <cstdint>
#include <iostream> /// for IO operations
#include <vector> /// for std::vector
/**
* @namespace backtracking
* @brief Backtracking algorithms
*/
namespace backtracking {
/**
* @namespace wildcard_matching
* @brief Functions for the [Wildcard
* Matching](https://www.geeksforgeeks.org/wildcard-pattern-matching/) problem.
*/
namespace wildcard_matching {
/**
* @brief The main function implements if pattern can be matched with given
* string
* @param s is the given matching string
* @param p is the given pattern
* @param pos1 is the starting index
* @param pos2 is the last index
* @returns 1 if pattern matches with matching string otherwise 0
*/
std::vector<std::vector<int64_t>> dpTable(1000, std::vector<int64_t>(1000, -1));
bool wildcard_matching(std::string s, std::string p, uint32_t pos1,
uint32_t pos2) {
uint32_t n = s.length();
uint32_t m = p.length();
// matching is successfull if both strings are done
if (pos1 == n && pos2 == m) {
return true;
}
// matching is unsuccessfull if pattern is not finished but matching string
// is
if (pos1 != n && pos2 == m) {
return false;
}
// all the remaining characters of patterns must be * inorder to match with
// finished string
if (pos1 == n && pos2 != m) {
while (pos2 < m && p[pos2] == '*') {
pos2++;
}
return pos2 == m;
}
// if already calculted for these positions
if (dpTable[pos1][pos2] != -1) {
return dpTable[pos1][pos2];
}
// if the characters are same just go ahead in both the string
if (s[pos1] == p[pos2]) {
return dpTable[pos1][pos2] =
wildcard_matching(s, p, pos1 + 1, pos2 + 1);
}
else {
// can only single character
if (p[pos2] == '?') {
return dpTable[pos1][pos2] =
wildcard_matching(s, p, pos1 + 1, pos2 + 1);
}
// have choice either to match one or more charcters
else if (p[pos2] == '*') {
return dpTable[pos1][pos2] =
wildcard_matching(s, p, pos1, pos2 + 1) ||
wildcard_matching(s, p, pos1 + 1, pos2);
}
// not possible to match
else {
return dpTable[pos1][pos2] = 0;
}
}
}
} // namespace wildcard_matching
} // namespace backtracking
/**
* @brief Self-test implementations
* @returns void
*/
static void test() {
// 1st test
std::cout << "1st test ";
std::string matching1 = "baaabab";
std::string pattern1 = "*****ba*****ab";
assert(backtracking::wildcard_matching::wildcard_matching(matching1,
pattern1, 0, 0) ==
1); // here the pattern matches with given string
std::cout << "passed" << std::endl;
// 2nd test
std::cout << "2nd test ";
std::string matching2 = "baaabab";
std::string pattern2 = "ba*****ab";
assert(backtracking::wildcard_matching::wildcard_matching(matching2,
pattern2, 0, 0) ==
1); // here the pattern matches with given string
std::cout << "passed" << std::endl;
// 3rd test
std::cout << "3rd test ";
std::string matching3 = "baaabab";
std::string pattern3 = "ba*ab";
assert(backtracking::wildcard_matching::wildcard_matching(matching3,
pattern3, 0, 0) ==
1); // here the pattern matches with given string
std::cout << "passed" << std::endl;
// 4th test
std::cout << "4th test ";
std::string matching4 = "baaabab";
std::string pattern4 = "a*ab";
assert(backtracking::wildcard_matching::wildcard_matching(matching4,
pattern4, 0, 0) ==
1); // here the pattern matches with given string
std::cout << "passed" << std::endl;
// 5th test
std::cout << "5th test ";
std::string matching5 = "baaabab";
std::string pattern5 = "aa?ab";
assert(backtracking::wildcard_matching::wildcard_matching(matching5,
pattern5, 0, 0) ==
1); // here the pattern matches with given string
std::cout << "passed" << std::endl;
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main() {
test(); // run self-test implementations
return 0;
}