Skip to content

Instantly share code, notes, and snippets.

@Gal3riel
Created February 28, 2016 23:56
Show Gist options
  • Save Gal3riel/1d3a6e5bffaaf4e13d32 to your computer and use it in GitHub Desktop.
Save Gal3riel/1d3a6e5bffaaf4e13d32 to your computer and use it in GitHub Desktop.
struct State;
typedef pair<char, State*> edge;
struct State {
bool fin;
vector<edge> edges;
State() {
fin = false;
}
};
State *constructNFA(string p) {
if (p.size() == 0) return NULL;
if (p.size() == 1 && p[0] == '*') return NULL;
State *init = new State();
State *curr = init;
unsigned int i = 0;
while (i < p.size()) {
if (p[i] == '*') {
i++; continue;
} else {
if (p[i+1] == '*') {
curr->edges.push_back({p[i], curr});
State *s = new State();
curr->edges.push_back({'@', s});
curr = s;
i += 2;
} else {
State *s = new State();
curr->edges.push_back({p[i], s});
curr = s;
i++;
}
}
}
curr -> fin = true;
return init;
}
void epsilonTransition(vector<State *> &states) {
unsigned int i = 0;
while (i < states.size()) {
for (edge e: states[i]->edges) {
if (e.first == '@') {
auto it = find(states.begin(), states.end(), e.second);
if (it == states.end())
states.push_back(e.second);
}
}
i++;
}
return;
}
class Solution {
public:
bool isMatch(string s, string p) {
if (s.size() == 0 && p.size() == 0) return true;
State *nfa = constructNFA(p);
if (!nfa) return false;
vector<State *> states = {nfa};
epsilonTransition(states);
for (char &c : s) {
vector<State *> next;
for (State *node : states) {
for (edge e : node->edges) {
if (e.first == '.') {
next.push_back(e.second);
}
if (e.first == c) {
next.push_back(e.second);
}
}
}
epsilonTransition(next);
states = next;
}
for (State *node : states) {
if (node -> fin)
return true;
}
return false;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment