DFA::DFA(const NFA& nfa) { allocPoint(); //create start point //std::map<std::set<int>, int> sim {{std::set<int>{0}, 0}}; //std::map<int, std::set<int> > ism {{0, std::set<int>{0}}}; //std::unordered_map<dynarray<int>, int, DynarrayHash<int> > n2d; std::map<std::set<int>, int> n2d; std::queue<std::set<int> > q; std::set<int> initClosure {0}; nfa.expandToEpsilonClosure(initClosure); n2d.emplace(initClosure, 0); q.push(std::move(initClosure)); while (!q.empty()) { std::set<int>& s = q.front(); q.pop(); int p = n2d[s]; std::vector<pair<int, int> > v; for (int sp : s) { for (auto& edge : nfa.m_graph[sp]) { if (edge.first != epsilon) v.push_back(edge); } } sort(v.begin(), v.end()); if (v.empty()) continue; pair<int, int> prev = v[0]; std::set<int> ns {prev.second}; for (int i = 1; i <= v.size(); ++i) { auto edge = std::make_pair(-1, -1);//a dummy edge never equal to prev if (i < v.size()) edge = v[i]; if (edge.first != prev.first) { int d = -1; nfa.expandToEpsilonClosure(ns); if (n2d.count(ns) == 0) { d = allocPoint(); n2d.emplace(ns, d); q.push(std::move(ns)); } else d = n2d[ns]; addEdge(p, prev.first, d); ns.clear(); } ns.insert(edge.second); prev = edge; } } }