Cod sursa(job #2256765)

Utilizator mihaicivMihai Vlad mihaiciv Data 9 octombrie 2018 09:31:26
Problema Trie Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 4.42 kb
#include <iostream>
#include <fstream>
#include <vector>
#define MOD 666013
using namespace std;
ifstream f("trie.in");
ofstream g("trie.out");

struct Node {
    int isFinished;
    Node *s[30];
    int nrAparitii;
    vector <int> a;
};

class Trie {
private:
    Node *N;
    void CreateTrie(string S, int pCurr, Node *&NCurr) {
        NCurr -> nrAparitii ++;
        if (NCurr == NULL) {
            NCurr = new Node();
            if (pCurr != S.size()) {
                char ch = S[pCurr];
                NCurr -> a.push_back(ch - 'a');
                //NCurr -> isFinished = false;
                NCurr->s[0] = new Node();
                CreateTrie(S, pCurr + 1, NCurr->s[1]);
            } else {
                NCurr -> isFinished ++;
                NCurr -> nrAparitii ++;
            }
        } else {
            if (pCurr != S.size()) {
                bool Found = false;
                char ch = S[pCurr];
                NCurr -> isFinished = false;
                int cValue = ch - 'a';
                for (int i = 0;i < NCurr->a.size() && !Found; ++ i) {
                    int p = NCurr->a[i];
                    if (p == cValue) {
                        Found = true;
                        CreateTrie(S, pCurr + 1, NCurr->s[i + 1]);
                    }
                }
                if (Found == false) {
                    NCurr->a.push_back(cValue);
                    int Size = NCurr->a.size();
                    NCurr->s[Size] = new Node();
                    CreateTrie(S, pCurr + 1, NCurr->s[Size]);
                }
            } else {
                NCurr -> isFinished ++;
            }
        }
    }

    int getCountNumber(string S, int pCurr, Node *NCurr) {
        if (pCurr == S.size() ) {
            return NCurr->isFinished;
        } else {
            char ch = S[pCurr];
            int cValue = ch - 'a';
            bool Found = false;
            for (int i = 0;i < NCurr -> a.size() && !Found; ++ i) {
                int p = NCurr -> a[i];
                if (p == cValue) {
                    Found = true;
                    return getCountNumber(S, pCurr + 1, NCurr->s[i + 1]);
                }
            }
            if ( !Found ) {
                return 0;
            }
        }
    }
    void deleteCurrentWord(string S, int pCurr, Node *NCurr) {
        NCurr -> nrAparitii --;
        if (pCurr == S.size() ) {
            NCurr->isFinished --;
        } else {
            char ch = S[pCurr];
            int cValue = ch - 'a';
            bool Found = false;
            for (int i = 0;i < NCurr -> a.size() && !Found; ++ i) {
                int p = NCurr -> a[i];
                if (p == cValue) {
                    Found = true;
                    deleteCurrentWord(S, pCurr + 1, NCurr->s[i + 1]);
                }
            }
        }
    }
    int getCommonPrefix(string S, int pCurr, Node *NCurr) {
        if (pCurr == S.size()) {
            return S.size();
        } else {
            if (NCurr -> nrAparitii == 0) {
                return pCurr - 1;
            } else {
                char ch = S[pCurr];
                int cValue = ch - 'a';
                bool Found = false;
                for (int i = 0;i < NCurr -> a.size() && !Found; ++ i) {
                    int p = NCurr -> a[i];
                    if (p == cValue) {
                        Found = true;
                        return getCommonPrefix(S, pCurr + 1, NCurr->s[i + 1]);
                    }
                }
                if ( !Found ) {
                    return pCurr;
                }
            }
        }
    }

public:

    Trie() {
        N = new Node;
    }

    void add(string S) {
        CreateTrie(S, 0, N);
    }
    int countNumber(string S) {
        return getCountNumber(S, 0, N);
    }

    void deleteWord(string S) {
        deleteCurrentWord(S, 0, N);
    }
    int getLongestCommonPrefix(string S) {
        return getCommonPrefix(S, 0, N);
    }
};

int main() {
    Trie T;
    int Type;
    string Word;
    while (f >> Type >> Word) {
        if (Type == 0) {
            T.add(Word);
        } else if (Type == 2) {
            g << T.countNumber(Word) << "\n";
        } else if (Type == 1) {
           T.deleteWord(Word);
        } else {
            g << T.getLongestCommonPrefix(Word) << "\n";
        }
    }

    return 0;
}