Я реализую суффикс trie в C++. Реализация контура Trie
приведена ниже.Доступ к первому символу строки без символов
#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
}
}
Я использую две структуры данных, Node
и Edge
, которые имеют некоторые методы получения и установки свойств и можно было ожидать. Метод childLoc()
возвращает местоположение ребра (если оно существует), представляющее заданный символ.
код компилируется нормально, но по какой-то причине, я получаю эту ошибку во время выполнения:
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)
Я сказал, что эта ошибка означает, что я доступ первый символ пустой строки, но я не вижу, где это происходит в коде.
вы отлажена код с помощью отладчика? например скомпилировать с флагом '-g' с g ++, а затем использовать отладчик на основе gdb для выполнения кода ... –
Очень сложно помочь вам с ошибкой времени выполнения, не имея возможности скомпилировать этот пример. Вы должны пройти через код с отладчиком на вашем конце. Если вы хотите получить ответ, вам нужно будет уменьшить пример и предоставить входные данные, которые создают вашу проблему. См. [Эту ссылку] (http://stackoverflow.com/help/mcve) о том, как создать полезный пример, который привлечет больше ответов. –
Итак, где-то вы не путаете ни одной нитки колбас с нитью колбас. Легко сделать, так как и std:; строка не может быть нулевой, в отличие от C char *. –