Cod sursa(job #1923498)

Utilizator 1475369147896537415369Andrei Udriste 1475369147896537415369 Data 11 martie 2017 10:23:52
Problema Trie Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 3.39 kb
#include <cstdio>
#include <cstring>
#include <cctype>
using namespace std;

struct node{
    int occurences;
    struct node *edge[26];

    node(){
        occurences = 0;
        for(int i = 0; i < 26; i++){
            edge[i] = NULL;
        }
    }
};
node *head = new node;

void Insert(char word[]){
    node *current = head;
    int len = strlen(word), index;

    for(int i = 0; i < len; i++, current = current -> edge[index]){
        index = tolower(word[i]) - 'a';

        if(current -> edge[index] == NULL){
            current -> edge[index] = new node;
        }
    }current -> occurences++;
}
int Search(char word[]){
    node *current = head;
    int len = strlen(word), index;

    for(int i = 0; i < len; i++, current = current -> edge[index]){
        index = tolower(word[i]) - 'a';
        if(current -> edge[index] == NULL) return 0;
    }
    return current -> occurences;
}
int LongestPrefix(char word[]){
    node *current = head;
    int len = strlen(word), index, prefix = 0;

    for(int i = 0; i < len; i++, current = current -> edge[index]){
        index = tolower(word[i]) - 'a';
        if(current -> edge[index] == NULL) break;
        prefix++;
    }
    return prefix;
}
void Delete(char word[]){
    node *ptr = head, *depth = NULL;
    int i, j=-1, k, index, len = strlen(word), verges = 0;

    for(i=0; i<len; i++, ptr = ptr -> edge[index]){
        index = tolower(word[i] - 'a');
        if(ptr -> edge[index] == NULL) return;
        if(i != len-1 && ptr -> occurences){
            depth = ptr;
            j = i;
        }
        verges = 0;

        for(k = 0; i && k < 26; k++){
            verges += !!(ptr -> edge[k]);
        }if(verges > 1 && i > j){
            j = i;
            depth = ptr;
        }
    }if(ptr -> occurences == 0) return;

    verges = 0;

    for(i=0; i<26; i++){
        verges += !!(ptr -> edge[i]);
    }
    if(ptr -> occurences > 1 || ((ptr -> occurences == 1) && verges)){
        ptr -> occurences--;
        return;
    }
    if(depth == NULL){
        index = tolower(word[0] - 'a');
        ptr = head -> edge[index];
        head -> edge[index] = NULL;

        for(i=1; i<len; i++){
            index = tolower(word[i] - 'a');
            node *temp = ptr;
            ptr = ptr -> edge[index];
            delete temp;
        }delete ptr;
    }else{
        k = len - j;
        index = tolower(word[j] - 'a');
        node *temp = depth;
        depth = depth -> edge[index];
        temp -> edge[index] = NULL;

        for(i=1; i<k; i++){
            index = tolower(word[j+i] - 'a');
            temp = depth;
            depth = depth -> edge[index];
            delete temp;
        }delete depth;
    }
}

int main(){

    freopen("trie.in", "r", stdin);
    freopen("trie.out", "w", stdout);

    int task;
    char word[21], ch = 0;

    while(1){

        scanf("%d", &task);
        scanf("%s", word);

        switch(task){
            case 0:
                   Insert(word);
                   break;
            case 1:
                   Delete(word);
                   break;
            case 2:
                   printf("%d\n", Search(word));
                   break;
            case 3:
                   printf("%d\n", LongestPrefix(word));
        }
        if((ch = getc(stdin)) == EOF) break;
    }
    return 0;
}