10.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. package main
  2. import "fmt"
  3. func isMatch(s string, p string) bool {
  4. // If former x chars of string matches former y chars
  5. // of pattern, match[x][y] == true, else == false
  6. var match [][]bool
  7. // Init match
  8. for i := 0; i < len(s)+1; i++ {
  9. row := make([]bool, len(p)+1)
  10. match = append(match, row)
  11. }
  12. // "" matches ""
  13. match[0][0] = true
  14. // Current & last char rank of pattern
  15. currP, lastP := 1, 0
  16. for currP <= len(p) {
  17. zeroOrMore := false
  18. // Current char of pattern
  19. charP := p[currP-1]
  20. if currP < len(p) && p[currP] == '*' {
  21. zeroOrMore = true
  22. currP++ // To skip '*'
  23. match[0][currP] = match[0][lastP] // .* pattern can match len 0 string
  24. }
  25. // Start from the first char of string
  26. for currS := 1; currS <= len(s); currS++ {
  27. charS := s[currS-1]
  28. if !zeroOrMore {
  29. // s1s2...sx ~ p1p2...py <=> s1...s(x-1) ~ p1...p(x-1) && sx ~ py
  30. match[currS][currP] = match[currS-1][lastP] &&
  31. (charP == '.' || charS == charP)
  32. } else {
  33. // ... <=> s1...sx ~ p1...p(y-1) [ie. py matches nothing] ||
  34. // (sx ~ sy && s1...s(x-1) ~ p1...py)
  35. match[currS][currP] = match[currS][lastP] ||
  36. ((charP == '.' || charS == charP) &&
  37. match[currS-1][currP])
  38. }
  39. }
  40. lastP = currP
  41. currP++
  42. }
  43. return match[len(s)][len(p)]
  44. }
  45. func main() {
  46. fmt.Println(isMatch("", ""))
  47. fmt.Println(isMatch("ssssss", "p"))
  48. fmt.Println(isMatch("ssssss", "s*"))
  49. fmt.Println(isMatch("ssssss", "s.*s"))
  50. fmt.Println(isMatch("ss", "s.*ss"))
  51. fmt.Println(isMatch("ss", "s*"))
  52. }