Cod sursa(job #2841961)

Utilizator manudragoDragomir Manuel manudrago Data 30 ianuarie 2022 19:42:27
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.99 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;
    int sons = 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->sons += 1;
            curr = new_node;
        }
    }
    curr->ap++;
}

bool remove_from_trie_recursively(Node* curr, char word[], int index, Node* root){
    if(index == strlen(word)){
        curr->ap--;
        if(curr->ap == 0 && curr->sons == 0){
            delete curr;
            return true;
        }
        return false;
    }
    bool is_deleted = remove_from_trie_recursively(curr->node[word[index] - 'a'], word, index + 1, root);
    if(is_deleted) {
        curr->node[word[index] - 'a'] = NULL;
        curr->sons--;
    }
    if(curr->sons == 0 && curr->ap == 0 && curr != root){
        delete curr;
        return true;
    }
    return false;
}

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

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) << "\n";
        }
        // 3 w - tipareste lungimea celui mai lung prefix comun al lui w cu oricare cuvant din lista
        else{
            fout << max_prefix_length(trie, word) << "\n";
        }
    }
    return 0;
}