CMU15-445 2023 spring p0

文章讲述了在Trie数据结构中使用智能指针std::unique_ptr和std::shared_ptr进行操作,涉及Get、Put、Remove函数的实现,强调了写入时复制策略以及处理多线程并发访问的锁管理。还提到了调试任务和大小写转换功能。
摘要由CSDN通过智能技术生成

预备知识

智能指针
std::unqiue_ptr std::shared_ptr
类型转化

const_cast dynamic_cast
task1
task2
task3
task4

task1

在此任务中,您将需要在trie.h和trie.cpp两个文件中修改和实现写入时复制尝试。在写入时复制 trie 中,操作不会直接修改原始 trie 的节点。相反,将为修改后的数据创建新节点,并为新修改的 trie 返回新的根。写入时复制使我们能够在每次操作后随时以最小的开销访问 trie。考虑在上面的示例中插入。我们通过重用原始树中的两个子节点并创建一个新的值节点 2 来创建一个新节点。(见下图)

在这里插入图片描述
这里需要实现三个函数
Get
Put
Remove

Get
这里Get是最容易实现的,通过遍历std::string_view key,若能找到对应的TrieNodeWithValue 则返回其value,否则返回nullptr。需要注意的是遍历到最后一个点的时候需要通过dynamic_cast将父类指针转换为子类指针。
由于dynamic_cast不能对智能指针操作因此通过**.get()**的方式获取裸指针

auto *now = dynamic_cast<const TrieNodeWithValue<T> *>(cur_node.get());
  return now ? now->value_.get() : nullptr;

Put

这里还是通过遍历std::string_view key当该结点没有的时候就停下,同时需要将已有的结点存入栈中用于之后的复制

while (idx < key_size && cur_node) {
    char ch = key[idx++];
    node_stack.push_back(cur_node);
    cur_node = cur_node->children_.find(ch) != cur_node->children_.end() ? cur_node->children_.at(ch) : nullptr;
  }
  if (idx != key_size || !cur_node || !cur_node->is_value_node_) {
    return *this;
  }

由于trie.h中声明了 TrieNode(std::map<char, std::shared_ptr<const TrieNode>> children) : children_(std::move(children)) {}不难想到通过子节点的方式生成父节点。
最后的叶子节点leaf_node为子节点

std::shared_ptr<const TrieNodeWithValue<T>>leaf_node = 
      cur_node ? std::make_shared<TrieNodeWithValue<T>>(cur_node->children_,value_node)
                :std::make_shared<TrieNodeWithValue<T>>(value_node);
std::shared_ptr<const TrieNode>child_node = leaf_node;

最后只需要从后往前遍历stack_node并返回Trie(cur_node)

Remove
Remove的思路和Put有些类似也是将出现的结点存入栈中,遍历到最后如果该点的children为空,则将该点释放,如果该点有value则删除value

task2

task2就是多个线程能读,一个线程能写,当读和写的时候都需要用到root_,这个时候root_lock_.lock();上完锁之后再unlock就好了
写入的时候还需要write_lock_.lock();

task3

task主要就是一个调试,由于随机数因为环境不同需要修改Trie_debug_test.cpp

task4

task4是实现一个大小写的转换

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值