【问题标题】:hashmap vs array of arrays for this instance此实例的 hashmap 与数组数组
【发布时间】:2016-05-01 17:15:45
【问题描述】:

我正在使用 C 编程语言并想问这个简单的问题。假设我有这样的数据结构:

typedef struct {
    char* tag;
    char* name;
    unsigned int id;
} object;

在其他语言中,您可以创建一个包含键和值对的哈希图,然后将它们放入其中。 C 没有内置的 hashmap,但我想我可以去使用一些第三方 hashmap 库,但这对我的用例来说可能有点过头了。

基本上,我希望有一些方法可以通过标签或 id 访问其中一些;有了一个数组或指针以及这个数组大小的变量,我几乎可以添加到列表中,按 id 或标签排序,或者在没有第三方库的情况下在 C 中做很多我想做的事情。

typedef struct {
    object** objects;
    unsigned int count;
} object_bag;

添加简单的功能,没有重复检查等......

void add_object(object* obj) {
     int count = objects->count++;
     objects[count] = calloc(1,sizeof(object*));
     objects[count] = obj;
}

在这种情况下,是否有任何理由使用哈希图?这不是性能优化问题,我也很好奇,但在某个时候这种数据结构会变得比哈希图更麻烦吗?

【问题讨论】:

  • 如何使用这种方法通过标签/名称访问?
  • 使用地图的要点是给定其密钥的恒定时间访问。这完全取决于您需要如何访问您的数据
  • 还要注意你的内存分配不正确
  • 取决于您必须管理的数据量,但如果没有那么多对象,那么一个简单的数组,具有基本管理,即使没有对元素进行排序也可能很有用。不要尝试过早的优化,使用一些轻量级的抽象,这样之后你就可以使用更复杂的高效结构。

标签: c arrays hashmap


【解决方案1】:

我看到你提供的代码的直接问题是你需要为你的整个 指针数组objects)分配一些空间[至少你省略这部分代码]。

似乎您尝试一次为单个数组单元分配空间,这不是数组的工作方式。 (数组需要是一块连续的内存,所以你需要预先分配整个数组)(见下面 Johan 的提示)

如果您想支持任意大小的集合,请准备好重新分配一些空间,以防您存储的对象多于之前为指针分配的空间。

由于您似乎不需要对数组的“随机访问”功能,因此您可以选择使用“链表”实现。它具有更容易增长的特性(只需分配一个新元素并将其链接到末尾)。

如果您在 posix 上开发,您可能希望使用“内置”sys/queue.h 链表实现:http://man7.org/linux/man-pages/man3/queue.3.html

如果我是你,我很可能会重用一个现成的库,以便能够直接使用最合适的数据结构。如果你做应用程序开发,glib 可能是一个不错的选择:https://developer.gnome.org/glib/stable/glib-Hash-Tables.html

【讨论】:

  • 我对为“object_bag”分配空间也有同样的想法。但也应该注意,“对象”使用指针。这意味着当指针的值超出范围时,您将无法再访问该值。例如,在 for 循环中生成“object”的内容并将其放入“object_bag”中,当您尝试访问循环外的值(除非已分配)时,会出现指针错误。
  • @JohanWentholt 哦,我看了一眼,当然为“指针”分配空间不足以存储实际对象的内容。谢谢!
  • 我最初忽略了bags对象的分配。我更喜欢对内存进行持续时间访问,因为我会知道何时将新对象添加到列表中或交换值。为了删除,我可以将索引设置为某个值,循环遍历数组并释放为该对象分配的内存。问题是目前我不知道这个应用程序会增长到多大,我想说现在不需要超过 200 个对象。从 gnome 看 glib,我可以在我的程序中使用他们的 glib.h 吗?
  • @user1610950 对于约 200 个对象的性能增益或损失对于单个用户交互式应用程序来说不会很明显。从数组列表中删除对象的一种方便方法是获取最后一个列表条目,并将其放入已删除对象所在的孔中,这样您的数组就可以很好地保持连续填充。要集成 glib,您需要在编译时添加头文件并在链接时添加库。如果您确信可以在可接受的时间内创建功能性数组列表实现并且性能并不重要,那么您可能会很好地使用您提出的数组列表方法。
猜你喜欢
  • 2011-09-21
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
  • 2016-08-16
  • 1970-01-01
  • 2012-12-28
相关资源
最近更新 更多