I.刚刚实现了一种位(基于Nedtries),但我的代码执行很多内存分配(对于每个节点)。与我的植入相反,在Othet事物中,NEDTRIS被认为是快速的,因为它们的内存分配少(如果有)。作者声称他的实施是“就地的”,但是在这种情况下,这意味着什么呢? Nedtries如何实现如此少量的动态内存分配?

PS:我知道来源可用,但是代码很难遵循,我无法弄清楚它是如何工作的

有帮助吗?

解决方案

我看了nedtrie.h源代码。似乎“就地”的原因是 必须将Trie簿记数据添加到您要存储的项目中。

您可以使用Nedtrie_entry宏将父/儿童/Next/prev链接添加到您的数据结构,然后可以将数据结构传递给各种TRIE例程,这些例程将提取和使用这些添加的成员。

因此,从某种意义上说,您可以增加现有的数据结构和Trie Code Piggybacks。

至少那就是它的样子。该代码中有很多宏观的优点,所以我本可以让自己感到困惑(:

其他提示

我是作者,所以这是为了众多Google的好处,他们同样在使用Nedtries方面遇到困难。我要感谢Stackflow上的人们没有对我个人发表不愉快的评论,而其他一些关于Nedtries的讨论也是如此。

  1. 恐怕我不明白知道如何使用它的困难。用法非常容易 - 只需复制readme.html文件中的示例:

typedef struct foo_s foo_t;
struct foo_s {
  NEDTRIE_ENTRY(foo_t) link;
  size_t key;
};
typedef struct foo_tree_s foo_tree_t;
NEDTRIE_HEAD(foo_tree_s, foo_t);
static foo_tree_t footree;

静态size_t fookeyFunct(const foo_t *限制r){return r-> key; }

nedtrie_generate(static,foo_tree_s,foo_s,link,fookeyFunct,nedtrie_nobblezeros(foo_tree_s));

int main(void){foo_t a,b,c, *r; nedtrie_init(&footree); A.Key = 2; nedtrie_insert(foo_tree_s,&footree,&a); B.Key = 6; nedtrie_insert(foo_tree_s,&footree,&b); r = nedtrie_find(foo_tree_s,&footree,&b);断言(r ==&b); C.Key = 5; r = nedtrie_nfind(foo_tree_s,&footree,&c);断言(r ==&b); /* nfind找到下一个最大的。倒置以倒入此 */ nedtrie_remove(foo_tree_s,&footree,&a); nedtrie_foreach(r,foo_tree_s和footree){printf(“%p,%u n”,r,r-> key); } nedtrie_prev(foo_tree_s,&footree,&a);返回0; }

您声明您的项目类型 - 这里是struct foo_s。您需要内部的nedtrie_entry(),否则它可以包含您喜欢的任何东西。您还需要一个密钥生成功能。除此之外,它是漂亮的样板。

我本人不会选择这种基于宏观的初始化系统!但这是与BSD rbtree.h的兼容性。因此,使用BSD rbtree.h,Nedtries很容易交换到任何东西上。

  1. 关于我对“适当”算法的使用,我想我缺乏计算机科学培训。我所说的“到位”是当您仅使用传递到一块代码的内存时,因此,如果您将64个字节交给了一个算法,则只会触摸64个字节,即不会使用额外的元数据,或分配一些额外的内存,或者确实写入全球状态。一个很好的示例是一个“适当的”排序实现,其中仅分类集合(我想线程堆栈)。

    因此,不,NEDTRIS不需要内存分配器。它将其所需的所有数据存储在nedtrie_entry和nedtrie_head宏扩展中。换句话说,当您分配struct foo_s时,您将对NEDTRIS进行所有内存分配。

  2. 关于理解“宏优点”,如果将逻辑编译为C ++,然后调试它,那么了解逻辑就容易得多:)。 C ++构建使用模板,调试器将在任何给定时间清洁显示您的声明。实际上,从我的结尾开始的所有调试都发生在C ++构建中,我精心将C ++的变化转换为宏观化C。

  3. 最后,在新版本之前,我搜索Google寻找我的软件问题的人,以查看我是否可以解决问题,通常我会惊讶于某人对我和我的免费软件的看法。首先,为什么那些遇到困难的人为什么不直接向我寻求帮助?如果我知道文档有问题,那么我可以修复它们 - 同样,在stackoverflow上询问并不会立即让我知道有一个文档问题bur宁愿依靠我找到下一个版本。因此,我要说的是,如果有人发现我的文档有问题,请给我发电子邮件并这样说,即使在StackFlow上有类似的讨论。

尼尔

到位 表示您在原始(输入)数据上操作,因此输入数据成为输出数据。 不地 意味着您具有单独的输入和输出数据,并且未修改输入数据。 到位 操作具有许多优势 - 较小的缓存/内存足迹,较低的内存带宽,因此通常更好的性能等,但是它们具有破坏性的不利条件,即您丢失了原始输入数据(根据它可能不重要,取决于或不重要,具体取决于在用例中)。

现场意味着操作输入数据并(可能)对其进行更新。这意味着输入数据没有复制和/移动。这可能会导致失去输入数据原始值,如果与您的特定情况相关,则需要考虑。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top