C ++字典trie实现

时间:2013-04-09 03:44:50

标签: c++ dictionary trie

我在我的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;
}

2 个答案:

答案 0 :(得分:4)

initNode创建一个新的Node并对其进行初始化,但随后将其丢弃。由于current是按值传递的,因此在函数内部修改initNode时,更改不会传播到void Dictionary::initNode(Node*& current) 之外。直截了当的解决方法是通过引用传递它:

{{1}}

答案 1 :(得分:1)

问题在于:

//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(&next);,在方法中,您可以取消引用当前内容以便能够编辑原始变量。