Skip to content

Commit d7cbdf0

Browse files
geeksforgeeks: add wildcard pattern matching
1 parent 2e62848 commit d7cbdf0

File tree

3 files changed

+100
-0
lines changed

3 files changed

+100
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Wildcard Pattern Matching
2+
3+
Given a text and a wildcard pattern,
4+
implement wildcard pattern matching algorithm that finds if wildcard pattern is matched with text.
5+
The matching should cover the entire text (not partial text).
6+
The wildcard pattern can include the characters ? and *.
7+
8+
- ? – matches any single character
9+
- * – Matches any sequence of characters (including the empty sequence)
10+
11+
## Copyright Notice
12+
13+
This problem is based on [content](https://www.geeksforgeeks.org/wildcard-pattern-matching/)
14+
from [GeeksforGeeks](https://www.geeksforgeeks.org)
15+
written by Aditya Goel
16+
and subject to [GeeksforGeeks copyright](https://www.geeksforgeeks.org/legal/copyright-information/).
17+
The original content from GeeksforGeeks and any modifications made here are attributed to GeeksforGeeks contributors,
18+
and this work is shared under [CC BY-SA 4.0](../LICENSE).
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package wildcard_pattern_matching
2+
3+
func Solution(text string, pattern string) bool {
4+
n, m := len(text), len(pattern)
5+
tStart, tEnd := 0, 0 // text window index
6+
pStart, pEnd := -1, 0 // pattern window index
7+
8+
for tEnd < n {
9+
if pEnd >= m {
10+
break
11+
}
12+
13+
if pattern[pEnd] == '?' || pattern[pEnd] == text[tEnd] {
14+
tEnd++
15+
pEnd++
16+
continue
17+
}
18+
19+
if pattern[pEnd] == '*' {
20+
tStart = tEnd
21+
pEnd++
22+
pStart = pEnd
23+
continue
24+
}
25+
26+
if pStart != -1 {
27+
tStart++
28+
tEnd = tStart
29+
pEnd = pStart
30+
continue
31+
}
32+
33+
return false
34+
}
35+
36+
for pEnd < m && pattern[pEnd] == '*' {
37+
pEnd++
38+
}
39+
40+
return pEnd == m
41+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package wildcard_pattern_matching_test
2+
3+
import (
4+
"testing"
5+
6+
sut "github.com/minizilla/minmax/geeksforgeeks/wildcard-pattern-matching"
7+
"github.com/minizilla/testr"
8+
)
9+
10+
func TestWildcardPatternMatching(t *testing.T) {
11+
tests := map[string]struct {
12+
text, pattern string
13+
matched bool
14+
}{
15+
"no wildcard matched": {"abcdef", "abcdef", true},
16+
"no wildcard unmatched": {"abcdef", "abcdez", false},
17+
"?: one": {"abcdef", "?bcdef", true},
18+
"?: middle": {"abcdef", "ab?def", true},
19+
"?: sides": {"abcdef", "?bcde?", true},
20+
"?: random": {"abcdef", "??cd?f", true},
21+
"?: unmatched": {"abcdef", "???d??f", false},
22+
"*: full matched": {"abcdef", "*abcdef", true},
23+
"*: one": {"abcdef", "*", true},
24+
"*: middle": {"abcdef", "a*f", true},
25+
"*: sides": {"abcdef", "*c*", true},
26+
"*: random": {"abcdef", "*cd***f", true},
27+
"*: multi-prefix": {"acccdef", "*ccd**f*", true},
28+
"*: unmatched": {"abcdef", "*d****d*", false},
29+
"combine: separate": {"abcdef", "*d?f", true},
30+
"combine: unite": {"abcdef", "*?f", true},
31+
"combine: unmatched": {"abcdef", "*f?", false},
32+
}
33+
34+
for name, tc := range tests {
35+
t.Run(name, func(t *testing.T) {
36+
assert := testr.New(t)
37+
matched := sut.Solution(tc.text, tc.pattern)
38+
assert.Equal(matched, tc.matched)
39+
})
40+
}
41+
}

0 commit comments

Comments
 (0)