Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Below is a clean Markdown (README.md) file that fully explains the entire regex matcher code, including:

✅ Feature overview ✅ Recursive + memoized explanation ✅ Iterative DP explanation ✅ Benchmarks ✅ Complexity ✅ Examples ✅ Visual diagrams


README.md (Complete Explanation Document)

# Regular Expression Matcher in Go  
Supports `.` and `*` Operators

This project implements a simplified regular expression engine in Go.  
It supports:

- `.` — matches **any one character**
- `*` — matches **zero or more** of the preceding character  
- Full backtracking prevention using **DP (Memoized Recursion + Iterative DP)**

This is equivalent to the behavior required in **LeetCode #10 – Regular Expression Matching**.

---

# 🚀 Features

✔ Complete recursive solution with memoization  
✔ Iterative bottom-up DP version  
✔ Full test suite  
✔ Go benchmarks  
✔ Handles complex expressions like:

"aab" vs "cab" → true "aaa" vs "abaca" → true "mississippi" vs "misisp." → false


---

# 📌 1. Recursive + Memoized Version (Top-Down DP)

The recursive version uses a function:

dp(i, j)


which checks:

> Does `s[i:]` match `p[j:]`?

### Why memoization?

Regex backtracking can explode exponentially (e.g., `aaa...` vs `a*a*a*...`).  
Memoization turns it into **O(m × n)**.

### Rules

#### 1. If pattern is finished  

match only if string is also finished


#### 2. Check first character match

firstMatch = s[i] == p[j] || p[j] == '.'


#### 3. If next pattern char is `*`  
Two choices:

  1. Skip "x*": dp(i, j+2)

  2. Use "*" at least once: firstMatch && dp(i+1, j)


#### 4. If no `*`  
Must match one character:

firstMatch && dp(i+1, j+1)


The memo map stores every `(i, j)` result to avoid recomputation.

---

# 📌 2. Iterative Bottom-Up DP Version

We build a DP matrix:

dp[i][j] = does s[:i] match p[:j] ?


Matrix size → `(len(s)+1) × (len(p)+1)`

### Base Case

dp[0][0] = true


### Patterns like `a*`, `a*b*`, etc.

for j in pattern: if p[j] == '*' and dp[0][j-1] == true: dp[0][j+1] = true


### DP Transitions

#### If characters match:

dp[i+1][j+1] = dp[i][j]


#### If encountering `*`:

- Zero occurrences:

dp[i+1][j+1] = dp[i+1][j-1]


- One/more occurrences:

if p[j-1] matches s[i]: dp[i+1][j+1] = dp[i][j+1]


---

# 📌 3. Test Cases

Examples used:

| String | Pattern | Expected |
|--------|---------|----------|
| `aa` | `a` | false |
| `aa` | `a*` | true |
| `ab` | `.*` | true |
| `aab` | `c*a*b` | true |
| `mississippi` | `mis*is*p*.` | false |
| `aaa` | `ab*a*c*a` | true |

---

# 📌 4. Benchmarks

Includes:

BenchmarkRecursive BenchmarkIterative BenchmarkLargeInput


Run:

go test -bench=.


Measures performance of both solutions.

---

# 📌 5. Complexity Analysis

Both versions run in:

### ⏱ Time: **O(m × n)**  
Every `(i, j)` state computed once.

### 💾 Space: **O(m × n)**  
Due to DP table or memo caching.

---

# 📌 6. Example Matching Breakdown

### Example  

s = "aab" p = "cab"


Pattern expands to:

c* → matches "" a* → matches "aa" b → matches "b"


Thus:

aab matches cab → true


---

# 📌 7. Visualization of DP Matrix

For string `"ab"` and pattern `".*"`:

| i\j | 0 | . | * |
|-----|---|---|---|
| 0 | T | F | T |
| a | F | T | T |
| b | F | F | T |

Final cell:

dp[2][2] = true


---

# 📌 8. File Structure

regex.go → full implementations + tests in main() regex_test.go → benchmarks README.md → explanation


---

# 📌 9. How to Run

Run the main program:

go run .


Run tests:

go test


Run benchmarks:

go test -bench=.


🎉 Conclusion

This Go project demonstrates a complete regex engine supporting . and * using two approaches:

  • Recursive memoized DP (clean and elegant)
  • Iterative bottom-up DP (efficient and iterative)

Both approaches guarantee O(m × n) performance with full correctness.

About

Regular expression matcher in Go supports '.' and '*' operators

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages