Cod sursa(job #3216878)

Utilizator BogdancxTrifan Bogdan Bogdancx Data 20 martie 2024 10:32:33
Problema NFA Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.01 kb
#include <iostream>
#include <fstream>
#include <unordered_map>
#include <unordered_set>
#include <queue>

class NFA {
public:
    NFA() = default;
    ~NFA() = default;

    void citesteNMK(std::ifstream &fin);

    void citesteStari(std::ifstream &fin);
    void citesteTranzitii(std::ifstream &fin);
    void citesteStareInitiala(std::ifstream &fin);
    void citesteStariFinale(std::ifstream &fin);

    bool isAccepted(const std::string &word);

private:
    std::unordered_map<int, std::unordered_map<int, std::unordered_set<char>>> m_graf;
    std::unordered_set<int> m_stariFinale;
    int m_stareInitiala;
};

void NFA::citesteNMK(std::ifstream &fin) {
    int n,m,k;
    fin>>n>>m>>k;
    for(int i = 1;i<=n;i++) {
        m_graf[i] = std::unordered_map<int, std::unordered_set<char>>();
    }
    fin>>m_stareInitiala;
    for(int i = 0; i < k; i++) {
        int sf;
        fin>>sf;
        m_stariFinale.insert(sf);
    }
    for(int i = 0; i < m; i++) {
        int x, y;
        char l;
        fin>>x>>y>>l;
        m_graf[x][y].insert(l);
    }
}

bool NFA::isAccepted(const std::string &word) {
    std::queue<std::pair<int, int>> nodes_to_visit;

    nodes_to_visit.emplace(m_stareInitiala, 0);

    while(!nodes_to_visit.empty()) {
        const std::pair<int, int> currentNode = nodes_to_visit.front();

        nodes_to_visit.pop();

        if(currentNode.second == word.length()) {
            if (m_stariFinale.find(currentNode.first) != m_stariFinale.end()) {
                return true;
            }
        }

        for(const auto &it: m_graf[currentNode.first]) {
            for(const char &letter: it.second) {
                if(letter == word[currentNode.second]) {
                    nodes_to_visit.emplace(it.first, currentNode.second + 1);
                }
            }
        }

    }

    return false;
}

void NFA::citesteStareInitiala(std::ifstream &fin) {
    fin>>m_stareInitiala;
}

void NFA::citesteStariFinale(std::ifstream &fin) {
    int numarStariFinale;
    fin>>numarStariFinale;
    for(int i = 0; i < numarStariFinale; i++) {
        int stareFinala;
        fin>>stareFinala;
        m_stariFinale.insert(stareFinala);
    }
}

void NFA::citesteStari(std::ifstream &fin) {
    int numarStari;
    fin>>numarStari;
    for(int i = 0; i < numarStari; i++) {
        int stare;
        fin>>stare;
        m_graf[stare] = std::unordered_map<int, std::unordered_set<char>>();
    }
}

void NFA::citesteTranzitii(std::ifstream &fin) {
    int numarTranzitii;
    fin>>numarTranzitii;
    for(int i = 0; i < numarTranzitii; i++) {
        int x, y;
        char l;
        fin >> x >> y >> l;
        m_graf[x][y].insert(l);
    }
}

int main() {
    std::ifstream fin("nfa.in");
    std::ofstream fout("nfa.out");
    NFA nfa;

    nfa.citesteNMK(fin);

    int nrCuvinte;

    fin>>nrCuvinte;

    for(int i = 0; i < nrCuvinte; i++) {
        std::string cuvant;
        fin>>cuvant;

        bool wasAccepted = nfa.isAccepted(cuvant);

        fout<<wasAccepted<<'\n';
    }

    fin.close();
    fout.close();
    return 0;
}