如何在C中构造和访问一组键值对?举一个简单的例子,假设我想创建一个在整数和它的平方根之间转换的表。如果我在写JavaScript,我可以这样做:
var squareRoots = { 4: 2, 9: 3, 16: 4, 25: 5 }
字符串然后像这样访问它们:
var squareRootOf25 = squareRoots[5]
型如果我想使用一种类型的枚举作为键,另一种类型的枚举作为值,该怎么办?
y3bcpkx11#
你可以考虑在C语言中实现哈希来实现这一点。有关哈希的基础知识,请参阅Wikipedia。请参阅此问题以了解更多细节和链接。这个link提供了很好的概述和实现细节。
eyh26e7m2#
没有内置的方法可以做到这一点,除非你在C99中这样初始化一个数组:
double squareRoots[] = { [4] = 2.0, [9] = 3.0, [16] = 4.0, [25] = 5.0, };
字符串但是,这会在数组中分配26个元素;其他值都是零。假设你不是这个意思,那么看看D R Hanson的C Interfaces and Implementations;它展示了一种实现关联数组(也称为哈希或字典)的方法。
oalqel3c3#
你也可以使用libghthash作为通用哈希。它们非常容易使用,并且可以集成到你的应用程序中。然而,它是第三方API -所以如果这是一个问题,你必须实现自己的。C中没有内置的关联数组/哈希表。数组初始化(C99)可能是最好的方法,除非你有非数字键:
T hash[] = { [1] = tObj, [255] = tObj2, };
字符串
yb3bgrhw4#
您可以使用作为clib库的一部分实现的map
balp4ylt5#
这个问题可以用map来解决。不幸的是,C中没有与map非常相似的数据结构**(map是一个以键值对方式存储元素的容器。每个元素都有一个唯一的键,用于访问对应的值。map通常被实现为平衡二叉搜索树,提供高效的查找和插入操作)**。这意味着你应该自己实现它。虽然这可能不是应对这个挑战的最佳方法,但我已经实现了一个使用二叉搜索树结构的Map,这并不保证最坏的时间复杂度不是线性的。另一种保证最坏的时间复杂度仍然是O(log2(n))的数据结构是自平衡红黑树。接下来我将介绍我在实现所要求的所谓Map方面的尝试。
#include <stdio.h> #include <stdlib.h> #include <string.h> struct Pair{ char *first; int second; }; struct Pair *make_pair(char *a,int b){ struct Pair *x=(struct Pair *)malloc(sizeof(struct Pair)); x->first=strdup(a); x->second=b; return x; }; int make_hash(char *s,int size){ unsigned long long hash=5813; for(int i=0;s[i];i++) hash=hash*33+s[i]; return (hash%size); } int compare(char *a,char *b){ //Hello! I am the compare function and I: // return -1, if a and b are the same. // return 0, if a "<" b. // return 1, if a ">" b. int i=0,x=0; for(;a[i]&&b[i];i++){ if(b[i]>a[i]) return 0; if(b[i]==a[i])x++; } if(!a[i]&&!b[i]&&x==i) return -1; if(!a[i]&&b[i]) return 0; return 1; }; struct Nod{ struct Pair *val; struct Nod *st,*dr; }; struct Tree{ struct Nod *top; }; void addtotree(struct Tree *t,char *s,int val){ if(!t->top){ t->top=(struct Nod *)malloc(sizeof(struct Nod)); t->top->val=make_pair(s,val); t->top->st=NULL; t->top->dr=NULL; return; }; struct Nod *nod=t->top; while(nod){ int x=compare(s,nod->val->first); if(x==1){ if(nod->dr){ nod=nod->dr; } else{ nod->dr=(struct Nod *)malloc(sizeof(struct Nod)); nod->dr->val=make_pair(s,val); nod->dr->dr=NULL; nod->dr->st=NULL; return; } } if(x==0){ if(nod->st){ nod=nod->st; } else{ nod->st=(struct Nod *)malloc(sizeof(struct Nod)); nod->st->val=make_pair(s,val); nod->st->dr=NULL; nod->st->st=NULL; return; } } if(x==-1){ nod->val->second=val; return; } } } void poptotree(struct Tree *t,char *s){ if(!t->top) return; int u=0; struct Nod *nod=t->top,*p=NULL,*te=NULL; while(nod){ te=nod; int x=compare(s,nod->val->first); if(x==1) nod=nod->dr,u=1; if(x==0) nod=nod->st,u=0; if(x==-1){ if(nod->st&&nod->dr){ struct Nod *search=nod->st,*pa=NULL; while(search->dr) pa=search,search=search->dr; if(pa){ pa->st=search->st; pa->dr=NULL; nod->val=make_pair(search->val->first,search->val->second); free(search->val); free(search); } else{ nod->st=nod->st->st; nod->val=make_pair(search->val->first,search->val->second); free(search->val); free(search); } return; } else if(!nod->st&&nod->dr){ if(p){ if(u){ p->dr=nod->dr; free(nod->val); free(nod); } else{ p->st=nod->dr; free(nod->val); free(nod); } } else{ t->top=nod->dr; free(nod->val); free(nod); } return; } else if(nod->st&&!nod->dr){ if(p){ if(u){ p->dr=nod->st; free(nod->val); free(nod); } else{ p->st=nod->st; free(nod->val); free(nod); } return; } else{ t->top=nod->st; free(nod->val); free(nod); return; } } else{ if(p){ if(u){ p->dr=NULL; free(nod->val); free(nod); } else{ p->st=NULL; free(nod->val); free(nod); } } else{ free(t->top->val); free(t->top); t->top=NULL; } } return; } p=te; } } struct Nod *findtotree(struct Tree *t,char *s){ struct Nod *nod=t->top; while(nod){ int x=compare(s,nod->val->first); if(x==1)nod=nod->dr; if(x==0)nod=nod->st; if(x==-1){ return nod; } } return NULL; } struct Map{ struct Tree **t; int size; }; struct Map *createMap(int size){ if(size<=0) return NULL; struct Map *m=(struct Map *)malloc(sizeof(struct Map)); m->size=size; m->t=(struct Tree **)calloc(size,sizeof(struct Tree *)); for(int i=0;i<size;i++) m->t[i]=NULL; return m; }; void add(struct Map *m,char *s,int val){ int hash=make_hash(s,m->size); if(!m->t[hash]){ m->t[hash]=(struct Tree *)malloc(sizeof(struct Tree)); m->t[hash]->top=NULL; }; addtotree(m->t[hash],s,val); }; void pop(struct Map *m,char *s){ int hash=make_hash(s,m->size); if(!m->t[hash]) return; poptotree(m->t[hash],s); }; int find(struct Map *m,char *s){ int hash=make_hash(s,m->size); if(!m->t[hash]) return 0; struct Nod *nod=findtotree(m->t[hash],s); if(nod) return nod->val->second; return 0; }; int main() { return 0; }
5条答案
按热度按时间y3bcpkx11#
你可以考虑在C语言中实现哈希来实现这一点。有关哈希的基础知识,请参阅Wikipedia。请参阅此问题以了解更多细节和链接。
这个link提供了很好的概述和实现细节。
eyh26e7m2#
没有内置的方法可以做到这一点,除非你在C99中这样初始化一个数组:
字符串
但是,这会在数组中分配26个元素;其他值都是零。
假设你不是这个意思,那么看看D R Hanson的C Interfaces and Implementations;它展示了一种实现关联数组(也称为哈希或字典)的方法。
oalqel3c3#
你也可以使用libghthash作为通用哈希。它们非常容易使用,并且可以集成到你的应用程序中。然而,它是第三方API -所以如果这是一个问题,你必须实现自己的。
C中没有内置的关联数组/哈希表。
数组初始化(C99)可能是最好的方法,除非你有非数字键:
字符串
yb3bgrhw4#
您可以使用作为clib库的一部分实现的map
balp4ylt5#
这个问题可以用map来解决。不幸的是,C中没有与map非常相似的数据结构**(map是一个以键值对方式存储元素的容器。每个元素都有一个唯一的键,用于访问对应的值。map通常被实现为平衡二叉搜索树,提供高效的查找和插入操作)**。这意味着你应该自己实现它。虽然这可能不是应对这个挑战的最佳方法,但我已经实现了一个使用二叉搜索树结构的Map,这并不保证最坏的时间复杂度不是线性的。另一种保证最坏的时间复杂度仍然是O(log2(n))的数据结构是自平衡红黑树。接下来我将介绍我在实现所要求的所谓Map方面的尝试。
字符串