Skip to content

Commit c41e670

Browse files
authored
Merge branch 'master' into backtracking_doc_improvements
2 parents 3b164e5 + faa58ed commit c41e670

File tree

2 files changed

+156
-0
lines changed

2 files changed

+156
-0
lines changed

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* [Subarray Sum](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/subarray_sum.cpp)
1212
* [Subset Sum](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/subset_sum.cpp)
1313
* [Sudoku Solve](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/sudoku_solve.cpp)
14+
* [Wildcard Matching](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/wildcard_matching.cpp)
1415

1516
## Bit Manipulation
1617
* [Count Of Set Bits](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/bit_manipulation/count_of_set_bits.cpp)

backtracking/wildcard_matching.cpp

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/**
2+
* @file
3+
* @brief Implementation of the [Wildcard
4+
* Matching](https://www.geeksforgeeks.org/wildcard-pattern-matching/) problem.
5+
* @details
6+
* Given a matching string and a pattern, implement wildcard pattern
7+
* matching with support for `?` and `*`. `?` matches any single character.
8+
* `*` matches any sequence of characters (including the empty sequence).
9+
* The matching should cover the entire matching string (not partial). The task
10+
* is to determine if the pattern matches with the matching string
11+
* @author [Swastika Gupta](https://github.com/Swastyy)
12+
*/
13+
14+
#include <cassert> /// for assert
15+
#include <iostream> /// for IO operations
16+
#include <vector> /// for std::vector
17+
18+
/**
19+
* @namespace backtracking
20+
* @brief Backtracking algorithms
21+
*/
22+
namespace backtracking {
23+
/**
24+
* @namespace wildcard_matching
25+
* @brief Functions for the [Wildcard
26+
* Matching](https://www.geeksforgeeks.org/wildcard-pattern-matching/) problem.
27+
*/
28+
namespace wildcard_matching {
29+
/**
30+
* @brief The main function implements if pattern can be matched with given
31+
* string
32+
* @param s is the given matching string
33+
* @param p is the given pattern
34+
* @param pos1 is the starting index
35+
* @param pos2 is the last index
36+
* @returns 1 if pattern matches with matching string otherwise 0
37+
*/
38+
std::vector<std::vector<int64_t>> dpTable(1000, std::vector<int64_t>(1000, -1));
39+
bool wildcard_matching(std::string s, std::string p, uint32_t pos1,
40+
uint32_t pos2) {
41+
uint32_t n = s.length();
42+
uint32_t m = p.length();
43+
// matching is successfull if both strings are done
44+
if (pos1 == n && pos2 == m) {
45+
return true;
46+
}
47+
48+
// matching is unsuccessfull if pattern is not finished but matching string
49+
// is
50+
if (pos1 != n && pos2 == m) {
51+
return false;
52+
}
53+
54+
// all the remaining characters of patterns must be * inorder to match with
55+
// finished string
56+
if (pos1 == n && pos2 != m) {
57+
while (pos2 < m && p[pos2] == '*') {
58+
pos2++;
59+
}
60+
61+
return pos2 == m;
62+
}
63+
64+
// if already calculted for these positions
65+
if (dpTable[pos1][pos2] != -1) {
66+
return dpTable[pos1][pos2];
67+
}
68+
69+
// if the characters are same just go ahead in both the string
70+
if (s[pos1] == p[pos2]) {
71+
return dpTable[pos1][pos2] =
72+
wildcard_matching(s, p, pos1 + 1, pos2 + 1);
73+
}
74+
75+
else {
76+
// can only single character
77+
if (p[pos2] == '?') {
78+
return dpTable[pos1][pos2] =
79+
wildcard_matching(s, p, pos1 + 1, pos2 + 1);
80+
}
81+
// have choice either to match one or more charcters
82+
else if (p[pos2] == '*') {
83+
return dpTable[pos1][pos2] =
84+
wildcard_matching(s, p, pos1, pos2 + 1) ||
85+
wildcard_matching(s, p, pos1 + 1, pos2);
86+
}
87+
// not possible to match
88+
else {
89+
return dpTable[pos1][pos2] = 0;
90+
}
91+
}
92+
}
93+
94+
} // namespace wildcard_matching
95+
} // namespace backtracking
96+
97+
/**
98+
* @brief Self-test implementations
99+
* @returns void
100+
*/
101+
static void test() {
102+
// 1st test
103+
std::cout << "1st test ";
104+
std::string matching1 = "baaabab";
105+
std::string pattern1 = "*****ba*****ab";
106+
assert(backtracking::wildcard_matching::wildcard_matching(matching1,
107+
pattern1, 0, 0) ==
108+
1); // here the pattern matches with given string
109+
std::cout << "passed" << std::endl;
110+
111+
// 2nd test
112+
std::cout << "2nd test ";
113+
std::string matching2 = "baaabab";
114+
std::string pattern2 = "ba*****ab";
115+
assert(backtracking::wildcard_matching::wildcard_matching(matching2,
116+
pattern2, 0, 0) ==
117+
1); // here the pattern matches with given string
118+
std::cout << "passed" << std::endl;
119+
120+
// 3rd test
121+
std::cout << "3rd test ";
122+
std::string matching3 = "baaabab";
123+
std::string pattern3 = "ba*ab";
124+
assert(backtracking::wildcard_matching::wildcard_matching(matching3,
125+
pattern3, 0, 0) ==
126+
1); // here the pattern matches with given string
127+
std::cout << "passed" << std::endl;
128+
129+
// 4th test
130+
std::cout << "4th test ";
131+
std::string matching4 = "baaabab";
132+
std::string pattern4 = "a*ab";
133+
assert(backtracking::wildcard_matching::wildcard_matching(matching4,
134+
pattern4, 0, 0) ==
135+
1); // here the pattern matches with given string
136+
std::cout << "passed" << std::endl;
137+
138+
// 5th test
139+
std::cout << "5th test ";
140+
std::string matching5 = "baaabab";
141+
std::string pattern5 = "aa?ab";
142+
assert(backtracking::wildcard_matching::wildcard_matching(matching5,
143+
pattern5, 0, 0) ==
144+
1); // here the pattern matches with given string
145+
std::cout << "passed" << std::endl;
146+
}
147+
148+
/**
149+
* @brief Main function
150+
* @returns 0 on exit
151+
*/
152+
int main() {
153+
test(); // run self-test implementations
154+
return 0;
155+
}

0 commit comments

Comments
 (0)