inline void test_multimap_insert(Multimap c) { using phx::arg_names::arg1; using phx::arg_names::arg2; using phx::arg_names::arg3; typename Multimap::value_type const value = *c.begin(); typename Multimap::iterator c_begin = c.begin(); std::size_t old_size = c.size(); // wrapper for // iterator insert(iterator where, const value_type& val); typename Multimap::iterator it = phx::insert(arg1, arg2, arg3)(c, c_begin, value); if (test(*it != value || c.size() != old_size + 1)) { cerr << "Failed " << typeid(Multimap).name() << " test_multimap_insert 1\n"; return; } // wrapper for // iterator insert(const value_type& val); typename Multimap::value_type const value2(1400, 2200); it = phx::insert(arg1, arg2)(c, value2); if (test(it == c.end())) { cerr << "Failed " << typeid(Multimap).name() << " test_multimap_insert 2\n"; return; } // wrapper for // template<class InIt> // void insert(InIt first, InIt last); Multimap const const_c = build_assoc<Multimap>(); typename Multimap::size_type size = c.size(); phx::insert(arg1, const_c.begin(), const_c.end())(c); if (test(c.size() != size + const_c.size())) { cerr << "Failed " << typeid(Multimap).name() << " test_multimap_insert 3\n"; return; } }
Automaton::Ref NfaToDfa(Automaton::Ref source, Multimap<State*, State*>& dfaStateMap) { Automaton::Ref target = shared_ptr<Automaton>(new Automaton); Multimap<Transition*, Transition*> nfaTransitions; vector<Transition*> transitionClasses;//保证转换先后顺序不被nfaTransitions.Keys破坏 State* startState = target->NewState(); target->startState = startState; dfaStateMap.insert(startState, source->startState); vector<State*> transitionTargets; vector<State*> relativeStates; for (int i = 0;i < target->states.size();i++) { // dfa中的待处理的结点 State* currentState = target->states[i].get(); nfaTransitions.clear(); transitionClasses.clear(); // 获得dfa结点对应的nfa的那个结点 // 对该DFA状态的所有等价NFA状态进行遍历 vector<State*> &nfaStates = dfaStateMap[currentState]; for (int j = 0;j < nfaStates.size();j++) { State* nfaState = nfaStates[j]; //对每一个NFA状态的所有转换进行遍历 for (int k = 0;k < nfaState->transitions.size();k++) { Transition* nfaTransition = nfaState->transitions[k]; //检查该NFA转换类型是否已经具有已经被记录 Transition* transitionClass = 0; for (auto it = nfaTransitions.begin();it != nfaTransitions.end();it++) { Transition* key = (*it).first; if (isTransitionEqual(key, nfaTransition)) { transitionClass = key; break; } } //不存在则创建一个转换类型 if (transitionClass == 0) { transitionClass = nfaTransition; transitionClasses.push_back(transitionClass); } //注册转换,一对多的结构 nfaTransitions.insert(transitionClass, nfaTransition); } } // 遍历上面获得的转换,transitionClasses就是将来可能会成为 // 某个dfa结点的边的结构,它的key是任意取的其中的一条边 for (int j = 0;j < transitionClasses.size();j++) { // 获得一条边对应的那些边 const vector<Transition*>& transitionSet = nfaTransitions[transitionClasses[j]]; // 获得那些边指向的结点集合 transitionTargets.clear(); for (int l = 0;l < transitionSet.size();l++) { State* nfaState = transitionSet[l]->target; if (!isElementExist(transitionTargets, nfaState)) { transitionTargets.push_back(nfaState); } } // 判断转换类的所有转换的NFA目标状态组成的集合是否已经有一个对应的DFA状态 State* dfaState = 0; for (auto it = dfaStateMap.begin();it != dfaStateMap.end();it++) { // 将DFA的等价NFA状态集合进行排序(不然不能compare对吧) // 话说我记得我当初也是这么写的 hh // dfaStateMap.CopyValuesToCollection(k, relativeStates); relativeStates.clear(); // 忘记清空了,debug了一年 for (auto i = 0;i < (*it).second.size();i++) { relativeStates.push_back((*it).second[i]); } // 先排下序,才能比较 sort(relativeStates.begin(),relativeStates.end()); sort(transitionTargets.begin(), transitionTargets.end()); // 比较两者是否相等 if (relativeStates.size() == transitionTargets.size()) { bool equal = true; for (int l = 0;l < relativeStates.size();l++) { if (relativeStates[l] != transitionTargets[l]) { equal = false; break; } } if (equal) { dfaState = (*it).first; break; } } } //不存在这个DFA状态则创建一个 if (!dfaState) { dfaState = target->NewState(); // 把刚刚得到的那些结点加进去 for (int k = 0;k < transitionTargets.size();k++) { dfaStateMap.insert(dfaState, transitionTargets[k]); if (transitionTargets[k]->finalState) { dfaState->finalState = true; } } } //将该转换复制到新状态机里 Transition* transitionClass = transitionClasses[j]; Transition* newTransition = target->NewTransition(currentState, dfaState); newTransition->range = transitionClass->range; newTransition->type = transitionClass->type; } } return target; }