如何从 hsearch 中删除元素

2023-12-04

我正在使用 GNU C 库提供的 hsearch_r 函数。

我发现虽然我可以使用 hsearch_r 将元素添加到哈希表中并将操作作为 ENTER 传递,但我看不出有什么方法可以从哈希表中删除元素或条目。

有人知道为什么会这样吗?

我可以执行以下操作来实现我的删除功能吗?

我首先使用 hsearch_r 进行搜索,操作为 FIND。然后,一旦我得到指向 hash_element 的指针,我就释放它。那行得通吗?如果我只能添加元素并搜索它们,那么哈希库有什么用呢?为什么不提供删除例程?

我尝试用谷歌搜索搜索库的源代码,但找不到它。有人也可以指点我吗?

http://linux.die.net/man/3/hcreate_r

EDIT:

我还看到,如果我使用 ADD 操作调用 hsearch_r 两次,那么它既不会抛出错误,也不会使用新值更新哈希。这很奇怪。这意味着 hsearch 内部不实现替换功能,我们必须自己执行此操作,即首先进行搜索,如果存在,则删除第一个条目,然后添加新条目。然而,要做到这一点,我们需要从哈希中删除一个元素,但我无法做到这一点。


The 来源hsearch_r可以在网上找到。

如果键在表中,则该函数在检查操作之前返回找到的条目,这意味着添加现有键的行为就像查找它一样。 (您可以在调用后覆盖“找到”结构的值hsearch(ADD)并覆盖旧值。)

该实现不适合元素删除。它维护一个存储桶数组。哈希冲突是通过寻找另一个空桶来处理的,因此桶索引不一定等于哈希码。当您插入两个具有相同哈希码的值时,第二个值将得到这样一个桶,其中哈希码不是桶索引。

现在,当您删除第一项,然后尝试查找第二项时,将找不到它,因为只有当哈希码为存储桶索引的“最佳”存储桶已满时,才会考虑“其他”存储桶。

除了不可更新的重新添加和缺失的删除选项外,还有其他限制hsearch_r。例如,必须事先估计最大条目数,并且以后不能更改。我认为hsearch_r旨在作为有限范围应用程序的快速哈希表。您可能会更好地使用另一个更通用的哈希表实现。

或者,您可以使用默认数据参数,表示“不存在”。的类型entry->data is void *, so NULL是一个显而易见的选择。以下数据是对手册页示例的修改,其中包含包装函数,其语法比hsearch_r:

#include <stdio.h>
#include <stdlib.h>

#define _GNU_SOURCE
#define __USE_GNU
#include <search.h>

#define NIL (-1L)

void hadd(struct hsearch_data *tab, char *key, long value)
{
    ENTRY item = {key, (void *) value};
    ENTRY *pitem = &item;

    if (hsearch_r(item, ENTER, &pitem, tab)) {
        pitem->data = (void *) value;
    }
}

void hdelete(struct hsearch_data *tab, char *key)
{
    ENTRY item = {key};
    ENTRY *pitem = &item;

    if (hsearch_r(item, FIND, &pitem, tab)) {
        pitem->data = (void *) NIL;
    }
}

long hfind(struct hsearch_data *tab, char *key)
{
    ENTRY item = {key};
    ENTRY *pitem = &item;

    if (hsearch_r(item, FIND, &pitem, tab)) {
        return (long) pitem->data;
    }
    return NIL;
}

int main()
{
    char *data[] = { 
        "apple", "pear", "cherry", "kiwi", 
        "orange", "plum", "pomegranate", NULL
    };
    char **p = data;

    struct hsearch_data tab = {0};
    int i;

    hcreate_r(10, &tab);
    for (i = 0; i < 5; i++) hadd(&tab, data[i], i + 1L);

    hdelete(&tab, "pear");
    hadd(&tab, "cherry", 144);

    while (*p) {
        long value = hfind(&tab, *p);

        if (value == NIL) {
            printf("%s: NIL\n", *p);
        } else {
            printf("%s: %ld\n", *p, value);
        }
        p++;
    }

    hdestroy_r(&tab);

    return 0;
}

注意:如果您使用 ponters 作为数据并且哈希表拥有该数据,则必须free数据会被破坏,而且当您覆盖现有值时也会如此。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从 hsearch 中删除元素 的相关文章

随机推荐

  • PHP 使用 Cookie 将当前会话 ID 存储在数据库中

    我创建了一个使用 cookie 并将会话 ID 存储在数据库中的登录系统 因此您的登录只能使用该特定会话 ID 我意识到这有几个问题 如果您在另一台设备上登录 会话 ID 会发生变化 不可多次登录 会话 ID 实际上是唯一标识用户已登录的内
  • 如何防止论坛类应用程序中出现垃圾邮件?

    对于网络应用程序 除了验证码之外 还有其他方法吗 Pastie org or p ramaz net 就我的口味而言 验证码对于小糊状物来说花费的时间太长了 你可以尝试蜜罐验证码 本质上 您可以使用 CSS 隐藏一些表单字段 您的用户永远不
  • System.in方法指定的键盘在哪里?

    我无法从概念上理解下面的代码 从键盘检索字符并打印到命令行 中我指定输入必须来自键盘的位置 public class Adder public static void main String arr Explain this next li
  • 无法将参数传递给 @selector 方法?

    我目前正在尝试使用标题为 X 的 UIButton 作为从视图中删除 Sprite 的方法 基本上 我的代码的工作原理是 当触摸精灵时 一条消息会发送到传递已选择的 Sprite 精灵的委托 视图控制器 在此方法中 我在该精灵之上绘制一个
  • Jquery 可选择范围选择(滑块行为)

    我想用值列表和选择范围的选项替换滑块 我关注了 jquery selectable 文章 它提供了一个很好的多选选项 http jqueryui com demos selectable display grid 由于我只需要范围选择 因此
  • 如何允许缺少 .d.ts 类型定义的模块?

    我正在使用一些不受欢迎的模块 例如Dyo and js sha3似乎没有任何类型 我现在并不真正关心第三方库中的类型 我不想花几个小时来输入这些类型 我主要将它用于服务器 以限制我的错误并在开发过程中更轻松地进行故障排除 I had a C
  • 从 JSONObjects 的 JSONArray 中删除除一个元素之外的所有元素

    我有一个像这样的 JSONArray org json a a b a c a d a e a f a g a 我想删除所有JSONObjects that do not有钥匙a 除了我幼稚的方法之外 还有更好的方法吗 Iterator o
  • Eclipse C++ 多个项目通用文件

    在 Eclipse CDT 中 我希望有几个 C 项目 projA projB projC 等 其中都包含一些 c cpp and or h来自公共目录的文件 这是我现有的文件结构 Workspace gt projA gt src gt
  • jQuery 将toggleClass 保存在cookie 或localStorage 中

    我正在尝试保存 cookie 或使用localStorage 以更好的为准 记住访问者何时单击加号按钮来显示 隐藏 div 任何人都可以协助使下面的代码与 cookie 一起使用或localStorage plus on click fun
  • 设计:注册登录尝试

    我有一个 Rails 3 0 项目使用devise我被要求在数据库中注册每次成功的登录和每次失败的尝试 来自devise我想我必须扩展文档FailureApp但这些示例只是重定向用户 根本没有使用该模型 在堆栈溢出我刚刚发现这个问题但仍未得
  • CultureInfo 的 2 个字母 ISO 国家/地区代码

    我有一个 Xamarin Forms 应用程序正在获取 GeoLocation 的 2 个字母的 ISO 国家 地区代码 我需要该应用程序以本地风格显示货币 因此 如果我将手机从英国带到日本 它会显示以日元格式设置的货币字段 设置十进制货币
  • Regex & BBCode - 完善嵌套报价

    我正在为我的网站编写一些 BBcode 我已经设法让大部分代码完美运行 但是 QUOTE 标签给了我一些悲伤 当我得到这样的东西时 QUOTE 1 QUOTE 2 This is a quote from someone else QUOT
  • 显示已过去时间

    我需要动态显示经过的时间 我的代码将根据间隔值弹出一条消息 public void button1 Click object sender EventArgs e this TopMost true DialogResult result1
  • Swift 线程 1:致命错误:init(coder:) 尚未实现(调用超级解决方案不起作用)

    嘿伙计们 我已经四处寻找 但仍然找不到解决我的问题的方法 我这里有一个自定义类 import UIKit DatasourceController is simply a UICollectionViewController that al
  • 使用套接字时发送当前值的 Unity 延迟

    Visual Studio 中的 client cs private void SendToServer string HeartRate SetHRTest HeartRate try s client GetStream StreamR
  • 通过 Javascript 预览 Html 文件上传

    我想为一篇文章展示预览之类的东西 所以通过 JS 获取详细信息 但问题来了
  • SVG onmouseover 对于具有重叠元素的组发生两次

    当将函数附加到onmouseoverSVG 组的事件
  • 如何隐藏图像的物理路径

    在我的应用程序中 我通过给出目录的物理路径来显示用户的图像 例如http www example com user images abcdefghijk jpg 但我不想向外部用户公开这个物理路径来访问直接文件 我想根据 gravtar 类
  • 如何在 scala 中将嵌套 JSON 转换为映射对象

    我有以下 JSON 对象 user id 123 data city New York timestamp 1563188698 31 session id 6a793439 6535 4162 b333 647a6761636b user
  • 如何从 hsearch 中删除元素

    我正在使用 GNU C 库提供的 hsearch r 函数 我发现虽然我可以使用 hsearch r 将元素添加到哈希表中并将操作作为 ENTER 传递 但我看不出有什么方法可以从哈希表中删除元素或条目 有人知道为什么会这样吗 我可以执行以