J'implémente un suffixe trie en C++. La mise en œuvre du contructeur Trie
peut être vue ci-dessous.Accès au premier caractère d'une chaîne sans caractères
#include <iostream>
#include <cstring>
#include "Trie.hpp"
using namespace std;
Trie::Trie(string T){
T += "#"; //terminating character
this->T = T;
nodes.reserve(T.length() * (T.length() + 1)/2); //The number of nodes is bounded above by n(n+1)/2. The reserve prevents reallocation (http://stackoverflow.com/questions/41557421/vectors-and-pointers/41557463)
vector<string> suffix; //vector of suffixes
for(unsigned int i = 0; i < T.length(); i++)
suffix.push_back(T.substr(i, T.length()-i));
//Create the Root, and start from it
nodes.push_back(Node("")); //root has blank label
Node* currentNode = &nodes[0];
//While there are words in the array of suffixes
while(!suffix.empty()){
//If the character under consideration already has an edge, then this will be its index. Otherwise, it's -1.
int edgeIndex = currentNode->childLoc(suffix[0].at(0));
//If there is no such edge, add the rest of the word
if(edgeIndex == -1){
addWord(currentNode, suffix[0]); //add rest of word
suffix.erase(suffix.begin()); //erase the suffix from the suffix vector
}
//if there is
else{
currentNode = (currentNode->getEdge(edgeIndex))->getTo(); //current Node is the next Node
suffix[0] = suffix[0].substr(1, suffix[0].length()); //remove first character
}
}
}
//This function adds the rest of a word
void Trie::addWord(Node* parent, string word){
for(unsigned int i = 0; i < word.length(); i++){ //For each remaining letter
nodes.push_back(Node(parent->getLabel()+word.at(i))); //Add a node with label of parent + label of edge
Edge e(word.at(i), parent, &nodes.back()); //Create an edge joining the parent to the node we just added
parent->addEdge(e); //Join the two with this edge
}
}
J'utilise deux structures de données, et Node
Edge
qui ont des accesseurs et des propriétés que vous attendez. La méthode childLoc()
renvoie l'emplacement d'une arête (si elle existe) représentant un caractère donné.
Le code compile très bien, mais pour une raison quelconque je reçois cette erreur lors de l'exécution:
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::at: __n (which is 0) >= this->size() (which is 0)
Aborted (core dumped)
On m'a dit que cette erreur signifie que j'accède le premier caractère d'une chaîne vide, mais je ne peut pas voir où cela se passe dans le code.
avez-vous débogué votre code avec un débogueur? par exemple. compiler avec l'indicateur '-g' avec g ++, puis utiliser un débogueur basé sur gdb pour passer par le code ... –
Il est très difficile de vous aider avec une erreur d'exécution sans pouvoir compiler l'exemple. Vous devez parcourir le code avec un débogueur de votre côté. Si vous voulez une réponse, vous devrez réduire l'exemple et fournir les données d'entrée qui produisent votre problème. Voir [ce lien] (http://stackoverflow.com/help/mcve) sur la façon de produire un exemple utile qui attirera plus de réponses. –
Donc, quelque part, vous avez confondu aucune chaîne de saucisses avec une chaîne de pas de saucisses. Facile à faire depuis et std:; chaîne ne peut pas être nulle, contrairement à un C char *. –