Cod sursa(job #2586065)

Utilizator marius004scarlat marius marius004 Data 19 martie 2020 18:10:54
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.69 kb
#include <fstream>
 
using namespace std;
 
ifstream f("trie.in");
ofstream g("trie.out");
 
const int CHAR = 26;
 
class Trie{
    
public:
    
    Trie *characters[CHAR];
    int aparitie_cuvant;
    int aparitie_litera;
    
    Trie(){
        aparitie_litera = aparitie_cuvant = 0;
        
        for(int i = 0;i < CHAR;++i)
            this->characters[i] = nullptr;
    }
    
    void insert(const string& key){
        
        Trie *iterator = this;
        
        for(int i = 0;i < key.size();++i){
            
            if(iterator->characters[ key[i] - 'a' ] == nullptr)
                iterator->characters[ key[i] - 'a' ] = new Trie();
            
            iterator->characters[ key[i] - 'a']->aparitie_litera++;
            iterator = iterator->characters[ key[i] - 'a'];
        }
        
        iterator->aparitie_cuvant++;
    }
    
    bool haveChildren(Trie *nod){
        
        for(int i = 0;i < CHAR;++i)
            if(nod->characters[i] != nullptr)
                return true;
        
        return false;
    }
    
    bool deleteStr(Trie *& nod,string key){
        
        if(key.empty()){
            
            if(!haveChildren(nod) && nod->aparitie_cuvant == 1 && nod->aparitie_litera == 1){
                nod->aparitie_litera = nod->aparitie_cuvant = 0;
                delete nod;
                nod = nullptr;
                return true;
            }
            
            nod->aparitie_cuvant--;
            nod->aparitie_litera--;
            return false;
        }
        
        bool canDelete = deleteStr(nod->characters[ key[0] - 'a' ],key.substr(1));
        
        if(canDelete){
            
            if(!haveChildren(nod) && nod->aparitie_litera == 1 && nod->aparitie_cuvant == 0){
                nod->aparitie_litera = nod->aparitie_cuvant = 0;
                delete nod;
                nod = nullptr;
                return true;
            }
            
            nod->aparitie_litera--;
            return false;
        }
        
        nod->aparitie_litera--;
        return false;
    }
    
    int aparitii(const string& key){
        
        Trie *iterator = this;
        
        for(int i = 0;i < key.size();++i){
            
            if(iterator->characters[ key[i] - 'a'] == nullptr)
                return 0;
            
            iterator = iterator->characters[ key[i] - 'a' ];
        }
        
        return iterator->aparitie_cuvant;
    }
    
    int prefix(const string&key){
        
        Trie *iterator = this;
        int cnt = 0;
        
        for(int i = 0;i < key.size();++i){
            
            if(iterator->characters[ key[i] - 'a' ] != nullptr && iterator->characters[ key[i] - 'a' ]->aparitie_litera >= 1)
                cnt++;
            else
                return cnt;
            
            iterator = iterator->characters[ key[i] - 'a' ];
        }
        
        return cnt;
    }
};
 
int nr;
string s;

void dfs(Trie *& nod){// sterg Trie-ul de pe heap
       
       bool hasChildren = false;
       for(int i = 0;i < CHAR;++i){
           
           if(nod->characters[i] != nullptr){
               dfs(nod->characters[i]);
               hasChildren = true;
           }
           
       }
       
       if(!hasChildren){
           nod->aparitie_litera = nod->aparitie_cuvant = 0;
           delete nod;
       }
}

int main(){
    
    Trie *root = new Trie();
    
    while(f >> nr >> s){
        
        if(nr == 0)
            root->insert(s);
        else if(nr == 1)
            root->deleteStr(root,s);
        else if(nr == 2)
            g << root->aparitii(s) << '\n';
        else if(nr == 3)
            g << root->prefix(s) << '\n';
    }
    
    dfs(root);//sterg trie-ul
    
    return 0;
}