Skip to content

Commit

Permalink
geeksforgeeks: add wildcard pattern matching
Browse files Browse the repository at this point in the history
  • Loading branch information
minizilla committed Dec 20, 2023
1 parent 2e62848 commit d7cbdf0
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 0 deletions.
18 changes: 18 additions & 0 deletions geeksforgeeks/wildcard-pattern-matching/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Wildcard Pattern Matching

Given a text and a wildcard pattern,
implement wildcard pattern matching algorithm that finds if wildcard pattern is matched with text.
The matching should cover the entire text (not partial text).
The wildcard pattern can include the characters ? and *.

- ? – matches any single character
- * – Matches any sequence of characters (including the empty sequence)

## Copyright Notice

This problem is based on [content](https://www.geeksforgeeks.org/wildcard-pattern-matching/)
from [GeeksforGeeks](https://www.geeksforgeeks.org)
written by Aditya Goel
and subject to [GeeksforGeeks copyright](https://www.geeksforgeeks.org/legal/copyright-information/).
The original content from GeeksforGeeks and any modifications made here are attributed to GeeksforGeeks contributors,
and this work is shared under [CC BY-SA 4.0](../LICENSE).
41 changes: 41 additions & 0 deletions geeksforgeeks/wildcard-pattern-matching/solution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package wildcard_pattern_matching

func Solution(text string, pattern string) bool {
n, m := len(text), len(pattern)
tStart, tEnd := 0, 0 // text window index
pStart, pEnd := -1, 0 // pattern window index

for tEnd < n {
if pEnd >= m {
break
}

if pattern[pEnd] == '?' || pattern[pEnd] == text[tEnd] {
tEnd++
pEnd++
continue
}

if pattern[pEnd] == '*' {
tStart = tEnd
pEnd++
pStart = pEnd
continue
}

if pStart != -1 {
tStart++
tEnd = tStart
pEnd = pStart
continue
}

return false
}

for pEnd < m && pattern[pEnd] == '*' {
pEnd++
}

return pEnd == m
}
41 changes: 41 additions & 0 deletions geeksforgeeks/wildcard-pattern-matching/solution_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package wildcard_pattern_matching_test

import (
"testing"

sut "github.com/minizilla/minmax/geeksforgeeks/wildcard-pattern-matching"
"github.com/minizilla/testr"
)

func TestWildcardPatternMatching(t *testing.T) {
tests := map[string]struct {
text, pattern string
matched bool
}{
"no wildcard matched": {"abcdef", "abcdef", true},
"no wildcard unmatched": {"abcdef", "abcdez", false},
"?: one": {"abcdef", "?bcdef", true},
"?: middle": {"abcdef", "ab?def", true},
"?: sides": {"abcdef", "?bcde?", true},
"?: random": {"abcdef", "??cd?f", true},
"?: unmatched": {"abcdef", "???d??f", false},
"*: full matched": {"abcdef", "*abcdef", true},
"*: one": {"abcdef", "*", true},
"*: middle": {"abcdef", "a*f", true},
"*: sides": {"abcdef", "*c*", true},
"*: random": {"abcdef", "*cd***f", true},
"*: multi-prefix": {"acccdef", "*ccd**f*", true},
"*: unmatched": {"abcdef", "*d****d*", false},
"combine: separate": {"abcdef", "*d?f", true},
"combine: unite": {"abcdef", "*?f", true},
"combine: unmatched": {"abcdef", "*f?", false},
}

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
assert := testr.New(t)
matched := sut.Solution(tc.text, tc.pattern)
assert.Equal(matched, tc.matched)
})
}
}

0 comments on commit d7cbdf0

Please sign in to comment.