Cod sursa(job #2682146)

Utilizator stefanpiturStefan Alexandru Pitur stefanpitur Data 7 decembrie 2020 21:35:30
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.58 kb
#include <iostream>
#include <cstdio>
#include <fstream>
#include <cstring>
using namespace std;

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

const int L = 20;
const int ALPHABET_SIZE = 26;
const int N = 100001;

struct TrieNode
{
    struct TrieNode *children[ALPHABET_SIZE];
    int appearances, usages;
    bool isEnd;
};

struct TrieNode *getNode(void)
{
    struct TrieNode *pNode = new TrieNode;
    pNode -> isEnd = false;
    pNode -> appearances = pNode -> usages = 0;

    for(int i = 0; i < ALPHABET_SIZE; i++)
        pNode -> children[i] = NULL;
    return pNode;
};

void insertTrie(struct TrieNode *root, string word){
    struct TrieNode *pCrawl = root;
    root -> usages += 1;

    for(int i = 0; i < (int)word.length(); i++){
        int letter = word[i] - 'a';
        if(!pCrawl -> children[letter])
            pCrawl -> children[letter] = getNode();

        pCrawl = pCrawl -> children[letter];
        pCrawl -> usages += 1;
    }

    pCrawl -> appearances += 1;
    pCrawl -> isEnd = true;
}

void removeTrie(struct TrieNode *root, string word){
    struct TrieNode *pCrawl = root;
    root -> usages -= 1;

    for(int i = 0; i < (int)word.length(); i++){
        int letter = word[i] - 'a';
        pCrawl = pCrawl -> children[letter];
        pCrawl -> usages -= 1;
    }

    if(pCrawl -> isEnd)
        pCrawl -> appearances -= 1;
}

int countAppearances(struct TrieNode *root, string word){
    struct TrieNode *pCrawl = root;

    for(int i = 0; i < (int)word.length(); i++){
        int letter = word[i] - 'a';
        if(!pCrawl -> children[letter])
            return 0;
        pCrawl = pCrawl -> children[letter];
    }

    if(pCrawl -> isEnd)
        return pCrawl -> appearances;
    return 0;
}

int longestCommonPrefix(struct TrieNode *root, string word){
    struct TrieNode *pCrawl = root;

    for(int i = 0; i < (int)word.length(); i++){
        int letter = word[i] - 'a';
        if(!pCrawl -> children[letter] || pCrawl -> children[letter] -> usages == 0)
            return i;
        pCrawl = pCrawl -> children[letter];
    }

    return (int)word.length();
}

int main()
{
    int op;
    string word;

    struct TrieNode *root = getNode();

    while(fin >> op >> word){
        if(op == 0)
            insertTrie(root, word);
        else if(op == 1)
            removeTrie(root, word);
        else if(op == 2)
            fout << countAppearances(root, word) << "\n";
        else
            fout << longestCommonPrefix(root, word) << "\n";
    }
    return 0;
}