在C++中创建trie/后缀树时减少内存使用
Reducing memory usage while making a trie/suffix tree in C++
我正在尝试用c++制作一个trie,现在我的基本数据结构是。。
struct node{
int count; no of times this node has been visited.
struct node* child[ALPHABET_SIZE]; // Let ALPHABET_SIZE be 26
}
当字符串大小变大时,会浪费大量已分配的内存。就像我们插入"he"
一样我们的树将是
root---->h--->e
|--->e
我们看到,在根目录中,分配的内存中只有2/26th
被使用如何改进。
一些非常基本的建议:
- 如果预测分支因子较低,请考虑为子级使用数组以外的其他元素。例如,您可以有一个字母到节点*对的数组,并对它们进行线性或二进制搜索(如果它们是有序的)。你也可以使用某种地图
- 如果您不希望计数为百万/数十亿,您也可以使用较小的整数大小进行计数
- 您可以从基于arena的分配器(即对象池)获取节点,而不是动态分配节点,从而避免了通常添加到堆上分配的对象中的堆分配开销
与其为每个节点创建一个固定大小的数组,不如创建一个包含1个元素的数组,并在插入子节点时调整其大小(用一个大小为+1的新数组替换它)。插入速度会较慢,因此您可以测试并更改大小调整算法(size+1或size*2或size+size/2),以便在速度太慢时减少分配。
使用邻接列表。
我们可以创建一个节点列表,而不是树。一个节点将是字典,每个字典都有"当前值"(字母表)和"下一个状态"(子节点的索引列表)。我们可以在节点中添加其他必需的属性。
在您的情况下:该列表将是-
[{"value":","next_state":[1]},{"value":"h","next_state":[2]},{"value":"e","next_state":[]}]
现在说,我们加上"他的"。列表将更新为:
[{"value":","next_state":[1]},{"value":"h","next_state":[2,3]},{"value":"e","next_state":[]},{"value":"i","next_state":[4]},}
注意,索引-1中节点的next_state
。我们有两个子节点——"e"answers"i"。
它非常高效且易于实现。然而,trie的操作将相当缓慢。
相关文章:
- 将字符串存储在c++中的稳定内存中
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- Win32编译器选项和内存分配
- 增量运算符与后缀混淆
- 当vector是tje全局变量时,c++中vector的内存管理
- 带内存和隔离功能的SQLite
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 迭代时从向量和内存中删除对象
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 为什么示例代码访问IUnknown中已删除的内存
- 如何在C++类内存结构中创建"spacer"?
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 如何针对特定情况调试和修复此双自由内存损坏问题
- 占用过多内存的大型 (10Mb) 文本的后缀树
- 在C++中创建trie/后缀树时减少内存使用