Regular Expression Matching (10)

This is a recursive state-machine approach to the problem. I think it's strictly worse than the DP, but it was fun to come up with.


_57
class Solution {
_57
public:
_57
struct state {
_57
char c;
_57
bool star;
_57
};
_57
_57
template <class II>
_57
auto pattern_as_states (II begin, II end, const string& p) {
_57
for (int i = 0; i < p.size(); i++) {
_57
if (next(begin) != end and p[i+1] == '*') {
_57
*begin++ = {p[i++], true};
_57
} else {
_57
*begin++ = {p[i], false};
_57
}
_57
}
_57
return begin;
_57
}
_57
_57
inline bool satisfies (char c, state s) {
_57
return (c == s.c or s.c == '.');
_57
}
_57
_57
template <class SI, class II>
_57
bool recursive_match(SI strBegin, SI strEnd, II begin, II end) {
_57
_57
if (strBegin == strEnd || begin == end) {
_57
while (begin != end && begin->star) begin++;
_57
return (strBegin == strEnd && begin == end);
_57
}
_57
_57
if (satisfies(*strBegin, *begin)) {
_57
if (begin->star)
_57
return recursive_match(strBegin, strEnd, begin+1, end)
_57
|| recursive_match(strBegin+1, strEnd, begin, end)
_57
|| recursive_match(strBegin+1, strEnd, begin+1, end);
_57
_57
else return recursive_match(strBegin+1, strEnd, begin+1, end);
_57
}
_57
_57
return begin->star and recursive_match(strBegin, strEnd, begin+1, end);
_57
}
_57
_57
array<state, 30> states {};
_57
_57
bool isMatch(const string s, const string p) {
_57
int pLen = p.size();
_57
auto ens = pattern_as_states(states.begin(), states.end(), p);
_57
_57
auto end = unique(states.begin(), ens,
_57
[](const state a, const state b) {
_57
return a.c == b.c and a.star and b.star;
_57
});
_57
_57
return recursive_match(s.begin(), s.end(), states.begin(), end);
_57
}
_57
};

If you found this solution helpful, consider leaving a star!