Cod sursa(job #1776044)

Utilizator danielNiculaeDaniel Niculae danielNiculae Data 10 octombrie 2016 21:39:48
Problema Trie Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 3.69 kb
#include "fstream"
#include "cstring"

using namespace std;

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

const int ALPHABET = 26 + 5;
const int WORDMAX = 20 + 5;

char word[WORDMAX];


class Node {
public:

    Node() {
        for(int i = 0 ; i < ALPHABET ; i++) {
            children[i] = NULL;
        }
        partial = 0;
        words = 0;
    }

    Node* children[ALPHABET + 1];
    int partial;
    int words;
};

Node* root = new Node();

void insert(Node* node, int wordIndex) {
//    fout << "Inserting: " << word[wordIndex] << "\n";
    node->partial++;
    if((word[wordIndex]) == '\0') {
        node->words++;
        return;
    }
    else {
        if(node->children[word[wordIndex] - 'a'] == NULL) {
//            fout << "New node!!!\n";
            node->children[word[wordIndex] - 'a'] = new Node();
        }
        insert(node->children[word[wordIndex] - 'a'], wordIndex + 1);
    }
}

void remove(Node* node, int wordIndex) {
//    fout << "Removing: " << word[wordIndex] << " in node: " << node << "\n";
    node->partial--;

    if(word[wordIndex] == '\0') {
        node->words--;
        return;
    }
    else {
        if(node->children[word[wordIndex] - 'a']->partial == 0) {
//            fout << "Made NULL: " << (word[wordIndex] - 'a') << "\n";
            node->children[word[wordIndex] - 'a'] = NULL;
        }
        else {
//            fout << "Going to child: " << word[wordIndex] << "\n";
            remove(node->children[word[wordIndex] - 'a'], wordIndex + 1);
        }
    }
}

int count(Node* node, int wordIndex) {
//    fout << "Counting: " << word[wordIndex] << "\n";
//    fout << "Counting next: " << *(word + 1) << "\n";
//    fout << "Is equal? : " << (*(word + 1) == '\0') << "\n";

    if(word[wordIndex] == '\0') {
//        fout << "In terminating if condition node is: " << node << "\n";
//        fout << "From count, returning: " << node->words << "\n";
        return node->words;
    }
    else {
        if(node->children[word[wordIndex] - 'a'] == NULL) {
            return 0;
        }
        else {
            return count(node->children[word[wordIndex] - 'a'], wordIndex + 1);
        }
    }
}

int prefix(Node* node, int wordIndex, int occurences, int currentLevel) {
//    fout << "Prefix: " << word[wordIndex] << " in node: " << node << "\n";
    if(word[wordIndex]  == '\0') {
        return currentLevel;
    }
    else {
//        if(node->children[word[wordIndex] - 'a'] != NULL) {
//            fout << "partial: " << (node->children[word[wordIndex] - 'a']->partial - occurences) << "\n";
//        }
        if(node->children[word[wordIndex] - 'a'] == NULL || (node->children[word[wordIndex] - 'a']->partial - occurences) < 0
                || node->children[word[wordIndex] - 'a']->partial == 0) {
            return currentLevel;
        }
        else {
            return prefix(node->children[word[wordIndex] - 'a'], wordIndex + 1, occurences, currentLevel + 1);
        }
    }
}

int main() {

    while(!fin.eof()) {
        int type;
        memset(word, 0, WORDMAX);
        fin >> type >> word;
        if(strlen(word) == 0) {
            //in case of empty line
            break;
        }
        word[strlen(word)] = '\0';

//        fout << "Word: " << word << "\n";
//        fout << "strlen(word): " << strlen(word) << "\n";

        if(type == 0) {
            insert(root, 0);
        }
        else if(type == 1) {
            remove(root, 0);
        }
        else if(type == 2) {
//            fout << "type 2\n";
            fout << count(root, 0) << "\n";
        }
        else {
            int occurences = count(root, 0);
//            fout << "occurences: " << occurences << "\n";
            fout << prefix(root, 0, occurences, 0) << "\n";
        }
    }
}