From d7cbdf04e95ccf9b49cf9ce204f5df66c04d19d6 Mon Sep 17 00:00:00 2001 From: Billy Zaelani Malik Date: Wed, 20 Dec 2023 15:37:39 +0700 Subject: [PATCH] geeksforgeeks: add wildcard pattern matching --- .../wildcard-pattern-matching/README.md | 18 ++++++++ .../wildcard-pattern-matching/solution.go | 41 +++++++++++++++++++ .../solution_test.go | 41 +++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 geeksforgeeks/wildcard-pattern-matching/README.md create mode 100644 geeksforgeeks/wildcard-pattern-matching/solution.go create mode 100644 geeksforgeeks/wildcard-pattern-matching/solution_test.go diff --git a/geeksforgeeks/wildcard-pattern-matching/README.md b/geeksforgeeks/wildcard-pattern-matching/README.md new file mode 100644 index 0000000..549c1c8 --- /dev/null +++ b/geeksforgeeks/wildcard-pattern-matching/README.md @@ -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). diff --git a/geeksforgeeks/wildcard-pattern-matching/solution.go b/geeksforgeeks/wildcard-pattern-matching/solution.go new file mode 100644 index 0000000..5174385 --- /dev/null +++ b/geeksforgeeks/wildcard-pattern-matching/solution.go @@ -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 +} diff --git a/geeksforgeeks/wildcard-pattern-matching/solution_test.go b/geeksforgeeks/wildcard-pattern-matching/solution_test.go new file mode 100644 index 0000000..4e4c90e --- /dev/null +++ b/geeksforgeeks/wildcard-pattern-matching/solution_test.go @@ -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) + }) + } +}