Lab 11 - Trie

Obiective

În urma parcurgerii articolului, studentul va fi capabil să:

  • înţeleagă noţiunea şi structura unui trie
  • construiască, în limbajul C++, un trie
  • utilizeze un trie

De ce?

Trie-ul, cunoscut și sub numele de arbore de prefixe(prefix tree) este un arbore de căutare care permite operații de inserare si cautare de elemente in complexitate O(L) (L - lungimea cheii).

De obicei trie-ul este folosit pentru a stoca string-uri si valori asociate acestora. Pe parcursul semestrului am studiat alte 2 structuri de date care pot efectua aceleasi operatii: hashtable-ul si arborele binar de cautare. De ce am studia inca o structura de date care poate realiza aceleasi operatii?

  • Trie-ul poate insera si cauta elemente in O(L), avand un timp de execuție mai mic decât un arbore binar de căutare balansat O(logN) si rezultate comparabile(uneori mai bune) ca un hashtable.
  • Trie-ul permite operatii de cautare mai avansate, putand efectua cautari eficiente după prefix sau pentru cuvinte cu un număr de caractere lipsă sau greșite.

Ce este un trie?

Un trie este o structura de tip arbore care reține asocieri de tip cheie - valoare. Fiecare nod reprezintă fie o cheie, fie prefixul uneia. Radacina utilizeaza pe post de cheie un string vid(””). Copiii rădăcinii reprezintă noduri asociate cheilor sau prefixelor de chei de dimensiune 1, iar copiii acestora reprezintă chei sau prefixe de chei de dimensiune 2 s.a.m.d. In concluzie putem spune ca pentru un nod aflat la distanta k de radacina, acesta are o cheie de lungime k.

Puteti observa in desenul de mai jos cum arata un trie. De observat ca nodurile ce contin valori sunt colorate cu mov(nodurile corespunzatoare cheilor “in” si “int” contin si ele valori, chiar daca nu sunt noduri frunza)

Implementare

Fiind un arbore, trie-ul va respecta formatul standard a acestei structuri de date. Fiecare nod contine copiii, retinuti de obicei intr-un vector si valoare.

Trie.h
#ifndef __TRIE_H
#define __TRIE_H
 
#include <cstdio>
#include <cstdlib>
#include <vector>
 
template <typename T>
class Trie
{
  public:
    Trie() {}
    Trie(int capacity, T value)
      : words_count(0),
        children(capacity, NULL),
        value(value) { }
    ~Trie() {}
 
    T get(string key) {
      //assert(key.length() > 0);
      //assert('a' <= key[0] && key[0] <= 'z');
 
      char c = key[0];
      if (children[c - 'a'] == NULL)
        return NULL;
 
      if (key.length() == 1)
        return children[c - 'a']->value;
 
      return children[c - 'a']->get(key.substr(1));
    }
    void insert(string key, T value){}
    T remove(string key){} // returns the value of the node to be removed
    int get_num_nodes_with_prefix(string key) {}
  private:
    int count;
    vector<Trie *> children;
    T value;
};
 
#endif // __TRIE_H

In functie de problema pe care dorim sa o rezolvam, capacitatea poate varia. In exemplul de mai jos vom alege cheile sa fie formate doar din litere mici ale alfabetului:

De observat ca programul de mai sus crapa, daca metoda este apelata cu stringul vid(””). In cadrul cursul de Programare Orientate de Obiecte veti invata de mecanismul de Exception Handling. Pana veti invata la POO despre exceptii va recomand utilizarea in cod a asserturilor, pentru validarea de argumente. Prin decomentarea primelor 2 linii, programul va preciza exact linia unde s-a produs eroarea, in cazul apelarii metodei cu argumente eronate

Exerciții

Bibliografie

sd-ca/2017/laboratoare/lab-11.txt · Last modified: 2018/02/19 15:34 by cosmin_ioan.petrisor
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0