这是this question的后续问题。
由于我solved的一部分,我觉得剩下的问题与第一部分无关,我决定将这两部分分成两个问题。
我已根据建议here使用POSIX hcreate
/ hsearch
实现了关联数组。
为了完整起见,以下是除上一个问题的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
&amp; foo
导致预期值:
bar
现在我稍微修改替换baz
,CCCTTCTTATCG
&amp; 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
为清楚起见,这里是相应的CCCTTCTTATCG
:
foo
正如您所看到的,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
的3次修改(如CCCTTCTTATCG
中的-1
),因此不应在哈希表中找到。
但是,这是相应的输出:
-1
如您所见,bbr
与hsearch
相关联,即使它从未存储过。
对于在存储上分配1
的所有字符串也是如此,因为它们在即将插入时已经在哈希中。
在上面较小的示例中,gpcl6win64-9.18.exe -sDEVICE=pdfwrite -sOutputFile=%1.pdf -dNOPAUSE %1.txt
也是如此。
为什么table = df[fields]
width = pandas.util.terminal.get_terminal_size() # find the width of the user's terminal window
pandas.set_option('display.width', width[0]) # set that as the max width in Pandas
print(table)
会为这些密钥返回error /IndentationError/
,即使它们从未插入过来?
答案 0 :(得分:5)
手册页指示key
应该是分配有malloc
的字符串。以下是手册页中的几个相关引用
hdestroy()函数为每个比较键调用free(3) 搜索表,但不是与密钥关联的数据项。
和
必须分配比较密钥(作为item.key传递给hsearch()) 如果action是ENTER并且调用了hdestroy(),则使用malloc(3)。
因此,使用action hsearch
调用ENTER
会在散列中存储指针,并且该指针应指向稍后可以释放的字符串。在您的代码中,您有一个单独的字符串缓冲区,每次向哈希表添加一个条目时,都会传递相同的指针(指向您的字符串缓冲区)。这会弄乱哈希表。
解决问题很简单。在store
函数中,在将条目添加到表之前,使用key
制作strdup
的副本。换句话说,替换
e.key=(char*)key;
带
e.key=strdup(key);