Доступ к первому символу строки без символов

Я реализую три суффикс в 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)

Мне сказали, что эта ошибка означает, что я обращаюсь к первому символу пустой строки, но я не могу видеть, где это происходит в коде.

3

Решение

Я вижу две части кода, которые потенциально ответственны за std::out_of_range:

Во-первых: следующее выражение может получить доступ к пустой строке в позиции 0, Это может произойти как (как показано во второй части), вы сжимаете строки, содержащиеся в suffix-вектор:

int edgeIndex = currentNode->childLoc(suffix[0].at(0));

Во-вторых, вы работаете с записями в suffix-вектор с риском, что строки будут короткими:

suffix[0] = suffix[0].substr(1, suffix[0].length());

операция substr также даст std::out_of_range если первый операнд (т.е. pos-argument) превышает длину массива (ср. строка :: зиЬзЬг):

pos: Позиция первого символа, который будет скопирован как подстрока. Если
это равно длине строки, функция возвращает пустое
строка. Если это больше, чем длина строки, он бросает
вне зоны доступа. Примечание. Первый символ обозначается значением 0
(не 1).

Чтобы выяснить, какое из этих выражений действительно отвечает за исключение, я бы посоветовался проконсультироваться с вашим отладчиком 🙂

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]