Created
February 28, 2016 23:56
-
-
Save Gal3riel/1d3a6e5bffaaf4e13d32 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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