C hsearch 查找之前未输入的值

2024-04-04

这是一个后续问题这个问题 https://stackoverflow.com/q/34749026/2451238.

Since I solved https://stackoverflow.com/a/34749797/2451238我感觉剩下的问题与第一个问题无关,所以我决定将这两部分分成两个问题。

我已经使用 POSIX 实现了关联数组hcreate/hsearch按照建议here http://rosettacode.org/wiki/Associative_arrays/Creation/C#To_fetch_or_store.

为了完整起见,这里是除main()上一个问题的函数:

#include <inttypes.h> /* intptr_t             */
#include <search.h>   /* hcreate(), hsearch() */
#include <stdio.h>    /* perror()             */
#include <stdlib.h>   /* exit()               */
#include <string.h>   /* strcpy()             */

void exit_with_error(const char* error_message){
  perror(error_message);
  exit(EXIT_FAILURE);
}
int fetch(const char* key, intptr_t* value){
  ENTRY e,*p;
  e.key=(char*)key;
  p=hsearch(e, FIND);
  if(!p) return 0;
  *value=(intptr_t)p->data;
  return 1;
}

void store(const char *key, intptr_t value){
  ENTRY e,*p;
  e.key=(char*)key;
  p = hsearch(e, ENTER);
  if(!p) exit_with_error("hash full");
  p->data = (void *)value;
}

这是一个稍微扩展的main()功能:

int main(){
  char a[4]="foo";
  char b[4]="bar";
  char c[4]="baz";
  char t[4]="";
  char y='\0';
  const char l[6]={'a','b','f','o','r','z'};
  intptr_t x=NULL;
  size_t i=0,j=0;

  if(!hcreate(50)) exit_with_error("no hash");

  strcpy(t,b);
  store(t,0);
  if(fetch(t,&x)) printf("stored %s-->%d\n",t,(int)x);
  else printf("%s not stored\n",t);

  for(i=0;i<3;++i){
    y=t[i];
    for(j=0;j<6;++j){
      if(l[j]==y) continue;
      t[i]=l[j];
      if(fetch(t,&x)) store(t,-1);
      else store(t,1);
      if(fetch(t,&x)) printf("stored %s-->%d\n",t,(int)x);
      else printf("%s not stored\n",t);
    }   
    t[i]=y;
  }

  strcpy(t,a); if(fetch(t,&x)) printf("read %s-->%d\n",t,(int)x); else printf("%s not found\n",t);
  strcpy(t,b); if(fetch(t,&x)) printf("read %s-->%d\n",t,(int)x); else printf("%s not found\n",t);
  strcpy(t,c); if(fetch(t,&x)) printf("read %s-->%d\n",t,(int)x); else printf("%s not found\n",t);

  exit(EXIT_SUCCESS);
}

正如你所看到的,我把字符串bar并将其与0。 然后,我将所有仅一个字母不同的单词从bar并将它们关联到1,如果之前没有添加过,或者-1否则。 最后,我查找foo, bar & baz得出预期值:

stored bar-->0
stored aar-->1
stored far-->1
stored oar-->1
stored rar-->1
stored zar-->1
stored bbr-->-1
stored bfr-->1
stored bor-->1
stored brr-->1
stored bzr-->1
stored baa-->1
stored bab-->1
stored baf-->1
stored bao-->1
stored baz-->1
foo not found
read bar-->0
read baz-->1

现在我稍微修改一下函数替换foo, bar & baz by CCCTTCTTATCG & CCCTTCATTGCG:

int main(){
  char a[13]="CCCTTCTTATCG"
            /*|||||| |  ||*/
  char b[13]="CCCTTCATTGCG";
  char t[13]="";
  char y='\0';
  const char l[4]={'A','C','G','T'};
  intptr_t x=NULL;
  size_t i=0,j=0;

  if(!hcreate(150)) exit_with_error("no hash");

  strcpy(t,a);
  store(t,0); 
  if(fetch(t,&x)) printf("stored %s-->%d\n",t,(int)x);
  else printf("%s not stored\n",t);

  for(i=0;i<12;++i){
    y=t[i];
    for(j=0;j<4;++j){
      if(l[j]==y) continue;
      t[i]=l[j];
      if(fetch(t,&x)) store(t,-1);
      else store(t,1);
      if(fetch(t,&x)) printf("stored %s-->%d\n",t,(int)x);
      else printf("%s not stored\n",t);
    }   
    t[i]=y;
  }

  strcpy(t,a); if(fetch(t,&x)) printf("read %s-->%d\n",t,(int)x); else printf("%s not found\n",t);
  strcpy(t,b); if(fetch(t,&x)) printf("read %s-->%d\n",t,(int)x); else printf("%s not found\n",t);

  exit(EXIT_SUCCESS);
}

为了清楚起见,这里是相应的diff:

29,32c29,32
<   char a[4]="foo";
<   char b[4]="bar";
<   char c[4]="baz";
<   char t[4]="";
---
>   char a[13]="CCCTTCTTATCG";
>             /*|||||| |  ||*/
>   char b[13]="CCCTTCATTGCG";
>   char t[13]="";
34c34
<   const char l[6]={'a','b','f','o','r','z'};
---
>   const char l[4]={'A','C','G','T'};
38c38
<   if(!hcreate(50)) exit_with_error("no hash");
---
>   if(!hcreate(150)) exit_with_error("no hash");
40c40
<   strcpy(t,b);
---
>   strcpy(t,a);
45c45
<   for(i=0;i<3;++i){
---
>   for(i=0;i<12;++i){
47c47
<     for(j=0;j<6;++j){
---
>     for(j=0;j<4;++j){
60d59
<   strcpy(t,c); if(fetch(t,&x)) printf("read %s-->%d\n",t,(int)x); else printf("%s not found\n",t);

如你看到的,CCCTTCATTGCG有 3 次编辑CCCTTCTTATCG (like foo from bar),因此不应在哈希表中找到。

然而,这是相应的输出:

stored CCCTTCTTATCG-->0
stored ACCTTCTTATCG-->1
stored GCCTTCTTATCG-->1
stored TCCTTCTTATCG-->1
stored CACTTCTTATCG-->1
stored CGCTTCTTATCG-->1
stored CTCTTCTTATCG-->1
stored CCATTCTTATCG-->1
stored CCGTTCTTATCG-->1
stored CCTTTCTTATCG-->1
stored CCCATCTTATCG-->1
stored CCCCTCTTATCG-->1
stored CCCGTCTTATCG-->1
stored CCCTACTTATCG-->1
stored CCCTCCTTATCG-->1
stored CCCTGCTTATCG-->1
stored CCCTTATTATCG-->1
stored CCCTTGTTATCG-->1
stored CCCTTTTTATCG-->1
stored CCCTTCATATCG-->1
stored CCCTTCCTATCG-->1
stored CCCTTCGTATCG-->1
stored CCCTTCTAATCG-->1
stored CCCTTCTCATCG-->1
stored CCCTTCTGATCG-->1
stored CCCTTCTTCTCG-->-1
stored CCCTTCTTGTCG-->-1
stored CCCTTCTTTTCG-->-1
stored CCCTTCTTAACG-->-1
stored CCCTTCTTACCG-->-1
stored CCCTTCTTAGCG-->-1
stored CCCTTCTTATAG-->-1
stored CCCTTCTTATGG-->-1
stored CCCTTCTTATTG-->-1
stored CCCTTCTTATCA-->-1
stored CCCTTCTTATCC-->-1
stored CCCTTCTTATCT-->-1
read CCCTTCTTATCG-->-1
read CCCTTCATTGCG-->1

如你看到的,CCCTTCTTATCG与....关联-1即使它从未被存储过。

对于所有获得的字符串也是如此-1分配在存储上,因为它们在即将插入时已经在哈希中了。

这也适用于bbr在上面的小例子中。

怎么会hsearch回报1即使从未插入过这些键?


手册页表明key应该是分配有的字符串malloc。以下是手册页中的一些相关引用

hdestroy() 函数为每个比较键调用 free(3) 搜索表,但不搜索与该键关联的数据项。

and

必须分配比较键(作为 item.key 传递给 hsearch()) 如果操作为 ENTER 并且调用 hdestroy(),则使用 malloc(3)。

所以打电话hsearch用行动ENTER在哈希中存储一个指针,并且该指针预计指向一个可以稍后释放的字符串。在您的代码中,您有一个字符串缓冲区,每次向哈希表添加一个条目时,您都会传递相同的指针(指向您的字符串缓冲区)。这会使哈希表变得混乱。

解决问题很简单。在里面store函数,复制key with strdup在将条目添加到表之前。换句话说,替换

e.key=(char*)key;

with

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

C hsearch 查找之前未输入的值 的相关文章

随机推荐

  • 从 json_encode($phpArray) 访问 JSON 对象值

    我是 JSON Javascript 新手 遇到了这种性质的问题 在我的 php 脚本中 我将 php 数组传递给 javascript 如下所示 echo img src misc arrow right png 在我的 JavaScri
  • 有没有用于集成复杂功能的 Haskell 库?

    如何在 Haskell 中对复杂的复值函数进行数值积分 有现成的库吗 数字工具 http hackage haskell org package numeric tools仅在卷轴上运行 我知道在复平面上只有线积分 所以我感兴趣的界面是这样
  • 无法压缩分区数量不等的 RDD

    现在我有3个这样的RDD rdd1 1 2 3 4 5 6 7 8 9 10 rdd2 11 12 13 14 rdd3 15 16 17 18 19 20 我想这样做 rdd1 zip rdd2 union rdd3 我想要的结果是这样的
  • NodeJS 模块与类

    对我来说 类与 NodeJS CommonJS 模块非常相似 您可以拥有许多它们 它们可以重复使用 它们可以互相使用 并且通常每个文件一个 是什么让模块与类如此不同 使用它们的方式不同 命名空间的差异也很明显 除此之外 它们对我来说似乎非常
  • PyQt_Fit:无法导入名称路径

    我正在尝试使用 PyQt Fit 我从 pip install pyqt fit 安装了它 但是当我导入它时它不起作用并显示以下消息 ImportError Traceback most recent call last
  • 使用 Bouncy Castle 在 Java 中复制“openssl smime”?

    我手上有个问题 我不懂 Java 的同事正在使用 OpenSSL 命令对文件进行签名 如下所示 openssl smime binary sign certfile WWDR pem signer passcertificate pem i
  • .fit() 层的 shuffle = 'batch' 参数如何在后台工作?

    当我使用以下方法训练模型时 fit 层的参数 shuffle 预设为 True 假设我的数据集有 100 个样本 批量大小为 10 当我设置shuffle True然后 keras 首先随机选择样本 现在 100 个样本具有不同的顺序 根据
  • 在 Android 应用程序中查看 MS Office 文件

    我正在尝试查看应用程序中的文件 例如音频 视频 PDF 等 我已经成功地做到了这一点 现在我正在尝试查看 Microsoft Office 文件 例如 doc docx xls 和 ppt 在android中有什么办法可以做到这一点 比如调
  • ViewModelProviders 无法在我的片段中工作

    这就是我正在尝试做的事情 Set an ArrayListFragment 内的对象 从观察者处获取该数组FragmentActivity容器 承载所有片段的活动 所以 我所做的如下 首先我创建了SharedViewModel我将从哪里设置
  • GTK+ CSS 一键式

    如何在 GTK 中为一个按钮设置颜色 GtkButton button8 border radius 20 border width 1 1 1 1 font Sans 16 color black background image gtk
  • 使用从 csv 文件读取的矩阵中的 corrplot 函数时,“dimnames”[2] 的长度不等于数组范围

    我想从 csv 文件读取数据 将其保存为矩阵并将其用于可视化 data lt read table Desktop Decision Tree cor test csv header F sep data V1 V2 V3 V4 V5 V6
  • 如何使用RDD API反转reduceByKey的结果?

    我有一个 key value 的 RDD 我将其转换为 key List value1 value2 value3 的 RDD 如下所示 val rddInit sc parallelize List 1 2 1 3 2 5 2 7 3 1
  • 在Gtk中,是否可以使小部件淡入淡出?

    我想要一个Label 或者至少是标签上的文字 进行快速淡入 看起来这是可能在混乱中 http blog didrocks fr index php post Design experience and demos in GTK Clutte
  • 找不到 Magick-config [重复]

    这个问题在这里已经有答案了 可能的重复 ImageMagick RMagick 无法安装 RMagick 2 13 1 找不到 Magick 配置 https stackoverflow com questions 3894225 imag
  • 为什么在循环之外生成随机数会导致它始终相同?

    当我在 while 循环内创建一个随机数作为局部变量时 一切正常 但是当我生成一个随机数作为全局变量时 我就会陷入无限循环 我不明白这会如何以及为什么会产生任何影响 目标是通过 While 循环输出所有小于 0 7 的随机数 这是创建无限循
  • OnResume 相机重新初始化黑屏

    我有个问题 初始化相机进行预览并使另一个应用程序进入焦点后 然后返回我的应用程序 预览显示为黑色 如果我继续拍照 它会拍摄我通常将相机指向的位置的照片 我在 OnResume 覆盖上做错了什么吗 相关代码如下 public void Rel
  • Safari 忽略 tabindex

    我在一个文本框旁边有 2 个按钮 在这两个按钮后面有另一个文本框 第一个文本框的 tabindex 为 1000 第一个按钮为 1001 第二个按钮为 1002 第二个文本框的 tabindex 为 1003 当我按 Tab 时 tabin
  • 在 Mac 终端的 vim 语法突出显示中启用斜体

    我想让 vim 以斜体显示我的评论 并且我知道我需要放置 cterm italic in the hi Comment 我正在使用的 color vim 文件中的行 然而 这对文本显示没有影响 我怀疑这与某些 Terminal app 设置
  • 如何在java中加载和使用本机库?

    我有一个 java 类 调用本机方法并尝试加载库 import java io UnsupportedEncodingException public class Main public static native String getMy
  • C hsearch 查找之前未输入的值

    这是一个后续问题这个问题 https stackoverflow com q 34749026 2451238 Since I solved https stackoverflow com a 34749797 2451238我感觉剩下的问