Barra
Bor è una struttura dati per memorizzare un insieme di stringhe, che è un albero con radici e simboli sui bordi. < /div>
Ogni vertice di boro corrisponde a un prefisso di qualche stringa aggiunta. Questo stesso prefisso si ottiene scrivendo in sequenza i caratteri sui bordi del percorso dalla radice a questo vertice. Allo stesso tempo, esattamente un vertice corrisponde a ciascun prefisso esistente. Bor root corrisponde a una stringa vuota.

Esempio di boro per {be, bee, can, cat, cd}



L'arancione indica i vertici che corrispondono alle parole dell'insieme stesso. Si chiamano terminali.

Di seguito è riportato il codice per conservare il boro e aggiungere linee ad esso. Questo metodo memorizza il foro attraverso un array. Esiste anche un'implementazione tramite puntatori, che viene presentata nel codice dell'attività per l'addestramento.
  // dimensione dell'alfabeto nelle parole considerate const int alfa = 26; // struttura per la parte superiore del trapano struct Nodo{ // vettore di spigoli sotto forma di tabella di adiacenza, ovvero: // next[0] - bambino quando si salta sul carattere numero 0 ('a') // next[1] - bambino quando si salta sul carattere numero 1 ('b') // eccetera. vettoresuccessivo; // Opzioni aggiuntive // in questo caso, l'altezza del vertice h e il flag di terminalita' int h; termine bool;; Nodo(int h) { next.resize(alph, -1); // inizialmente senza spigoli questo->h = h; // l'altezza è uguale a quella specificata termine=falso; // top non è il terminale per impostazione predefinita } }; // elenco di vertici, inizialmente root ad altezza zero vettore trie(1, Nodo(0)); // funzione per aggiungere una stringa al boro void add(const string& s) { intero v = 0; // numero del vertice corrente, partendo dalla radice forn(i, (int)s.size()) { int c = s[i] - 'a'; // ottiene il numero del carattere corrente nella stringa // se la transizione desiderata non esiste ancora, ne creeremo una nuova if (trie[v].next[c] == -1) { trie[v].next[c] = (int)trie.size(); // il nuovo numero di vertice è   // dimensione del trapano corrente (con numerazione 0) trie.push_back(Node(trie[v].h + 1)); // crea un nuovo vertice con altezza 1 in più } v = trie[v].next[c]; // si sposta lungo il bordo desiderato } // quando siamo arrivati ​​in cima,   // che corrisponde all'intera stringa,   // quindi contrassegnalo come terminale trie[v].term = vero; }
Se hai bisogno di supportare l'eliminazione delle righe dal boro, probabilmente si rivelerà disonesto. Cioè, rimuovi semplicemente il flag terminale (o, forse, invece del flag, dovrai memorizzare un numero variabile) e lascia invariato l'albero di boro stesso.

Pertanto, inserimento/ricerca/cancellazione scorretta funzionano in tempo lineare dalla lunghezza della stringa di query.

Lo stesso boro, nel peggiore dei casi, occuperà O(n|Σ|) memoria, dove n è la lunghezza totale di tutte le stringhe, e Σ > - l'alfabeto delle stringhe utilizzate.

Per risolvere questo problema, la teoria dell'analisi del gioco ti aiuterà molto: https://e-maxx.ru/algo/games_on_graphs