コード例 #1
0
void findEqualientStates() {
    // inv precalc:
    for(int i = 1; i <= n; i++) {
        State *state = states[i];
        
        if(!state->toTerminal || !state->fromStart) {
            continue;
        }
        
        for(int c : alphabet) {
            State *to = state->to[c];
            
            if(to != NULL) {
                _inv[to->id][c].push_back(state->id);
            }
        }
    }
    
    for(int i = 1; i <= n; i++) {
        if(!states[i]->toTerminal || !states[i]->fromStart) {
            continue;
        }
        
        if(states[i]->isTerminal) {
            tmp1.insert(states[i]);
            _class[states[i]->id] = 0;
        } else {
            tmp2.insert(states[i]);
            _class[states[i]->id] = 1;
        }
    }
    
    Class *ff = new Class(tmp1);
    Class *ss = new Class(tmp2);
    
    if(tmp1.size() > 0) {
        p.push_back(ff);
    }
    
    if(tmp2.size() > 0) {
        p.push_back(ss);
    }
    
    for(int c : alphabet) {
        q.push(make_pair(ff, c));
        q.push(make_pair(ss, c));
    }
    
    tmp1.clear();
    tmp2.clear();
    
    while(!q.empty()) {
        pair<Class *, int> &cur = q.front();
        involved.clear();
        
        for(State * q : * (cur.first)) {
            for(int r : _inv[q->id][cur.second]) {
                int i = _class[r];
                involved[i].insert(states[r]);
            }
        }
        
        for(auto & pr : involved) {
            int i = pr.first;
            
            if(pr.second.size() < p[i]->size()) {
                int j = p.size();
                p.push_back(new Class());
                
                for(State * r : pr.second) {
                    p[i]->erase(r);
                    p[j]->insert(r);
                    _class[r->id] = j;
                }
                
                for(int c : alphabet) {
                    q.push(make_pair(p[j], c));
                    t++;
                }
            }
        }
        
        q.pop();
    }
    
    for(int i = 1; i <= n; i++) {
        if(!states[i]->toTerminal || !states[i]->fromStart) {
            _class[states[i]->id] = -1;
        }
    }
}