Cod sursa(job #2593172)

Utilizator horiacoolNedelcu Horia Alexandru horiacool Data 3 aprilie 2020 05:02:27
Problema Trie Scor 0
Compilator c-64 Status done
Runda Arhiva educationala Marime 2.96 kb
#include <fstream>
#include <stdlib.h>
#include <string.h>
using namespace std;

ifstream fin("trie.in");
ofstream fout("trie.out");

#define ALPHABET_SIZE 26
#define MAX_WORD_SIZE 40

typedef struct trie {
   int count, pref;
   struct trie* next[ALPHABET_SIZE];
} trie_t;
 
void add(trie_t *trie, int n, char *word) {
    trie_t* node = trie;
    int it, k = 0;
 
    while (k < n) {
        it = word[k] - 'a';

        if (node->next[it] == NULL) {
            node->next[it] = (trie_t *) malloc(sizeof(trie_t));
            node->next[it]->count = 0;
            node->next[it]->pref = 0;
 
            for(int i = 0; i < ALPHABET_SIZE; ++i) {
                node->next[it]->next[i] = NULL;
            }
        }
 
        node->next[it]->pref++;
 
        if (k == n - 1) {
            node->next[it]->count++;
        }
 
        node = node->next[it];
        k++;
    }
}

void del(trie_t *trie, int n, char *word) {
    trie_t* node = trie;
    trie_t* prev = trie;
    trie_t* tmp;
    int prev_it, it, k = 0, ok = 0;
 
    it = word[k] - 'a';
    node = node->next[it];
 
    while (node != NULL && k < n) {
        node->pref--;

        if (node->pref == 0) {
            tmp = node;
            ++ok;
        }
 
        if (k == n - 1) {
            node->count--;
        }
 
        prev_it = word[k++] - 'a';
        it = word[k] - 'a';
        node = node->next[it];
 
        if (ok == 0) {
            prev = prev->next[prev_it];
        } else if(ok == 1) {
            prev->next[prev_it] = NULL;
        }
 
        if (ok != 0) {
            free(tmp);
        }
    }
}
 
int find(trie_t *trie, int n, char *word) {
    trie_t* node = trie;
    int it, k = 0;
    int count = 0;

    while (node != NULL && k < n) {
        it = word[k] - 'a';
 
        if (node->next[it] != NULL && k == n - 1) {
            count = node->next[it]->count;
        }
 
        node = node->next[it];
        k++;
    }
 
    return count;
}
 
int longest_prefix(trie_t *trie, int n, char *word) {
    trie_t* node = trie;
    int it, k = 0;
    int length = 0;
 
    while (node != NULL && k < n) {
        it = word[k] - 'a';
 
        if (node->next[it] != NULL && node->next[it]->pref > 0) {
            length = k + 1;
        }
 
        node = node->next[it];
        k++;
    }
 
    return length;
}

int main() {
    trie_t *trie;
    char word[MAX_WORD_SIZE];
    int n, type;

    trie = (trie_t *) malloc(sizeof(trie_t));
    for(int i = 0; i < ALPHABET_SIZE; ++i) {
        trie->next[i] = NULL;
    }

    while (fin >> type) {
        fin >> word;
        n = strlen(word);

        switch (type) {
            case 0:
                add(trie, n, word);
                break;
            case 1:
                del(trie, n, word);
                break;
            case 2:
                fout << find(trie, n, word) << '\n';
                break;
            default: // 3
                fout << longest_prefix(trie, n, word) << '\n';
                break;
        }
    }

    return 0;
}