偶然之间发现今年的lab0不再是之前枯燥的矩阵操作,变成了一个并发安全的前缀树。感觉很有意思,特此记录一下。
遇到的C++语法问题
(C++语法是真的恶心)
unique_ptr
这里用到很多make_unique的创建方式,比如:
InsertChildNode(key[i], std::make_unique<TrieNode>(key[i]));
root_ = std::make_unique<TrieNode>('\0');
注意版本要更新到14,否则没有这个方法。
在插入、删除的时候需要进行遍历,但是unique_ptr不可以直接进行赋值,应该使用二级指针进行包裹
auto cur = &root_;
cur = (*cur)->GetChildNode(key[i]);
父类显式的构造函数
这里是本来本地测试都过了,但是在线测试死活过不了。在深度遍历CSDN后发现原来是TrieNodeWithValue的构造函数里有一个
TrieNodeWithValue(char key_char, T value)
这里构造函数会调用父类的构造函数,如果按照我原来这么写的话
TrieNodeWithValue(char key_char, T value) {
key_char_ = key_char;
value_ = value;
is_end_ = true;
}
会报
/autograder/bustub/src/include/primer/p0_trie.h:228:3: error: constructor for ‘bustub::TrieNodeWithValue’ must explicitly initialize the base class ‘bustub::TrieNode’ which does not have a default constructor
TrieNodeWithValue(char key_char, T value) {
^
需要改成这样:
TrieNodeWithValue(char key_char, T value) : TrieNode(key_char) {
// key_char_ = key_char;
value_ = value;
is_end_ = true;
}
Trie树的操作
插入
插入很简单,只需要从根节点开始遍历,没有的话就new一个下来就行
但是这里有两个坑
1、root是不包含信息的。所以在遍历的终止条件应该+1.
2、根节点需要是with value类型,这里可以先在上次遍历中构造出来初始的node,然后调用构造函数转换成with value的就可以
删除
删除这里注释要求使用递归,但是在使用递归的时候千万不要忘记先确认一遍有这个节点,要不然会出一些奇怪的错误
获取值
这里如果没有值的话应该返回return T(),千万不要返回其他的。
附上AC的截图:
需要代码可以私聊。