【问题标题】:C++ dictionary trie implementationC++字典树实现
【发布时间】:2013-03-31 08:25:10
【问题描述】:

我的insert 函数出现段错误:

current->isWord = true;

一切编译正常,没有警告或错误 (g++ -Wall -Wextra)。我的main 函数只调用了一次insert 函数,它不会工作。这是我的代码;它是我的.h.cpp 文件的混合体:

const int alphabetSize = 26;

struct Node
{
    bool isWord;
    Node* child[alphabetSize];
};

Dictionary::Dictionary()
{
    initNode(head); //Node* head; is defined in my .h file under private:
}

bool Dictionary::isPrefix(string s)
{
    Node* current = endOfString(s, false);
    if (current == NULL)
    {
        return false;
    }
    else
    {
        return true;
    }
}

bool Dictionary::isWord(string s)
{
    Node* current = endOfString(s, false);
    if (current == NULL)
    {
        return false;
    }
    else
    {
        return current->isWord;
    }
}

void Dictionary::insert(string s)
{
    Node* current = endOfString(s, true);
    current->isWord = true; //segfault here
}

//initializes a new Node
void Dictionary::initNode(Node* current)
{
    current = new Node;
    current->isWord = false;
    for (int i = 0; i < alphabetSize; i++)
    {
       current->child[i] = NULL;
    }
}

//returns a pointer to the Node of the last character in the string
//isInsert tells it whether it needs to initialize new Nodes
Node* Dictionary::endOfString(string s, bool isInsert)
{
    Node* current = head;
    Node* next = head;
    for (unsigned int i = 0; i < s.length(); i++)
    {
        if (isalpha(s[i]) == true)
        {
            int letter = (tolower(s[i]) - 'a');
            next = current->child[letter];
            if (next == NULL)
            {
                if (isInsert == false)
                {
                    return NULL;
                }

                initNode(next);
                current->child[letter] = next;
            }
            current = current->child[letter];
        }
    }

    return current;
}

【问题讨论】:

  • 为什么insert()没有NULL检查?
  • @iammilind:因为它将true 传递给endOfString,而不是像其他时候那样传递false
  • @icktoofay,如果head 为NULL 并且s.length() = 0Dictionary::endOfString(..) 方法中会发生什么?我们还需要在这种情况下进行 NULL 检查。
  • @iammilind: head 不会是 NULL 如果 initNode 是固定的; initNode 在构造函数中被调用。

标签: c++ dictionary trie


【解决方案1】:

initNode 创建一个新的Node 并对其进行初始化,但随后将其丢弃。因为current 是按值传递的,所以在函数内部对其进行修改时,更改不会传播到initNode 之外。直接的解决方法是让它通过引用传递:

void Dictionary::initNode(Node*& current)

【讨论】:

    【解决方案2】:

    问题出在这里:

    //initializes a new Node
    void Dictionary::initNode(Node* current)
    {
        current = new Node;
        current->isWord = false;
        for (int i = 0; i < alphabetSize; i++)
        {
           current->child[i] = NULL;
        }
    }
    

    current 是按值传入的,因此当您在方法中更改 current 时,您正在更改传入内容的副本,而不是外部变量。尝试传入一个Node** current,它是指向您的指针的指针,以便您可以编辑原始变量。你会这样称呼它; initNode(&amp;next); 并且在该方法中,您将取消引用 current 以便能够编辑原始变量。

    【讨论】:

      猜你喜欢
      • 2015-07-16
      • 1970-01-01
      • 2023-04-10
      • 2012-04-20
      • 1970-01-01
      • 1970-01-01
      • 2011-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多