Cod sursa(job #2841935)

Utilizator manudragoDragomir Manuel manudrago Data 30 ianuarie 2022 19:03:12
Problema Trie Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.41 kb
#include <iostream>
#include <fstream>
#include <cstring>

using namespace std;


const int ALPHABET = 26;
ifstream fin("trie.in");
ofstream fout("trie.out");

/**
node[i] = node[curr_letter - 'a']
*/
struct Node{
    int ap = 0;
    Node* node[ALPHABET];
};


struct Trie{
    Node* root;
};

void add_in_trie(Trie* t, char word[]){
    int len_word = strlen(word);

    Node* curr = t->root;
    for(int i = 0; i < len_word; i++){
        if(curr->node[word[i] - 'a'] != NULL){
            curr = curr->node[word[i] - 'a'];
        }else{
            Node* new_node = new Node();
            curr->node[word[i] - 'a'] = new_node;
            curr = new_node;
        }
    }
    curr->ap++;
}

bool remove_from_trie_recursively(Node* curr, char word[], int index){
    if(index == strlen(word)){
        curr->ap--;
        //check if curr node can be deleted
        if(curr->ap == 0){
            bool is_last = true;
            for(int i = 0; i < ALPHABET && is_last; i++){
                if(curr->node[i] != NULL){
                    is_last = false;
                }
            }
            if(is_last == true){
                delete curr;
            }
            return is_last;
        }
        return false;
    }
    bool is_deleted = remove_from_trie_recursively(curr->node[word[index] - 'a'], word, index + 1);
    if(is_deleted) {
        curr->node[word[index] - 'a'] = NULL;
    }
    if(is_deleted && curr->ap == 0){
        bool is_last = true;
        for(int i = 0; i < ALPHABET && is_last; i++){
            if(curr->node[i] != NULL){
                is_last = false;
            }
        }
        if(is_last == true){
            curr = NULL;
            delete curr;
        }
        return is_last;
    }
    return false;
}

void remove_from_trie(Trie* t, char word[]){
    remove_from_trie_recursively(t->root, word, 0);
}

int get_occ_of_word(Trie* t, char word[]){
    int len_word = strlen(word);

    Node* curr = t->root;
    for(int i = 0; i < len_word; i++){
        if(curr->node[word[i] - 'a'] == NULL){
            return 0;
        }else{
            curr = curr->node[word[i] - 'a'];
        }
    }
    return curr->ap;
}

int max_prefix_length(Trie* t, char word[]){
    int len_word = strlen(word);

    Node* curr = t->root;
    int curr_prefix_length = 0;
    for(int i = 0; i < len_word; i++){
        if(curr->node[word[i] - 'a'] == NULL){
            return curr_prefix_length;
        }else{
            curr = curr->node[word[i] - 'a'];
            curr_prefix_length += 1;
        }
    }
    return curr_prefix_length;
}


int main()
{
    Trie* trie = new Trie();
    trie -> root = new Node();
    int t;
    char word[21];
    while(fin >> t >> word){
        // 0 w - adauga o aparitie a cuvantului w in lista
        if(t == 0){
            add_in_trie(trie, word);
        }
        // 1 w - sterge o aparitie a cuvantului w din lista
        else if(t == 1){
            remove_from_trie(trie, word);
        }
        // 2 w - tipareste numarul de aparitii ale cuvantului w in lista
        else if(t == 2){
            fout << get_occ_of_word(trie, word) << endl;
        }
        // 3 w - tipareste lungimea celui mai lung prefix comun al lui w cu oricare cuvant din lista
        else{
            fout << max_prefix_length(trie, word) << endl;
        }
    }
    return 0;
}