OJ:http://acm.hdu.edu.cn/showproblem.php?pid=1880
题意还是非常的清楚,给你一个键值对,需求是给出k的时候,查出v,给你v的时候,查出k。还要注意的是,输出结果的时候,k中的[]是不会被输出的,但是查询的时候给出的k是包含[]的,且题中说明了魔咒个和字符串中都不会包含[]这两个字符。
解析:
其实这个题,使用有标准库的语言非常好实现,只是c语言没有,就稍微麻烦一点。
因为这是结题,我们完全没有必要去写一个动态的链式结构的HashMap,因为题目中说明了数量,所以我们只需要一次性开足够的空间就可以,要一次性开足够的空间就不能使用链表了,直接使用数组结构来替代链表。
之前的设想是直接使用一个hashmap,对k和v分别作为键值存一次,但是这样直接导致了空间不够,后来就改成了两个HashMap,两个map一个以k为键,一个一v为键。
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#define MAX 100010
// map的node
typedef struct{
char c[25];
char f[85];
// 因为使用的是数组来充当链式结构,所以这里的next指向的是下一个node的坐标
int next;
}Node;
// 一个map,以k作为键,v作为值
Node n1[MAX];
// 一个mao,以v作为键,k作为值
Node n2[MAX];
// 保存某一个hash值的链在n1数组中开始位置,然后n1数组中的node会将该hash值下的所有node连接起来
// 这个主要就是一个开始作用
int hIndex1[MAX];
int hIndex2[MAX];
// n1中待使用空间的开始下标
int curIndex1 = 0;
int curIndex2 = 0;
void init(){
memset(hIndex1,-1,sizeof(hIndex1));
memset(hIndex2,-1,sizeof(hIndex2));
for(int i=0;i<MAX;i++){
n1[i].next = -1;
n2[i].next = -1;
}
}
int hashcode(char *s){
int seed = 131;
int hash = 0;
while(*s){
hash = hash*seed + *s++;
}
return (hash&0x7fffffff);
}
void push(char *c,char *f){
strcpy(n1[curIndex1].c,c);
strcpy(n1[curIndex1].f,f);
int hash = hashcode(c)%MAX;
// 新的node直接放在链的开始位置
n1[curIndex1].next = hIndex1[hash];
// hIndex中保存的是新node的index
hIndex1[hash] = curIndex1++;
strcpy(n2[curIndex2].c,c);
strcpy(n2[curIndex2].f,f);
hash = hashcode(f)%MAX;
n2[curIndex2].next = hIndex2[hash];
hIndex2[hash] = curIndex2++;
}
int search1(char *c){
int hash = hashcode(c)%MAX;
if(hIndex1[hash] == -1){
return -1;
}
int index = hIndex1[hash];
for(;index!=-1;){
if(!strcmp(n1[index].c,c)){
return index;
}
index = n1[index].next;
}
return -1;
}
int search2(char *f){
int hash = hashcode(f)%MAX;
if(hIndex2[hash] == -1){
return -1;
}
int index = hIndex2[hash];
for(;index!=-1;){
if(!strcmp(n2[index].f,f)){
return index;
}
index = n2[index].next;
}
return -1;
}
int main(){
init();
char k[25],v[105];
char line[150];
for(;1;){
gets(line);
if(line[0] == '@'){
break;
}
int len = strlen(line);
int i=0;
for(;i<len;i++){
if(line[i] ==']'){
k[i] = line[i];
break;
}
k[i] = line[i];
}
k[++i] = 0;
int p = 0;
for(i=i+1;i<len;i++){
v[p++] = line[i];
}
v[p] = 0;
push(k,v);
}
int count;
scanf("%d", &count);
getchar();
for(;count>0;count--){
gets(line);
int index;
if(line[0] == '['){
index = search1(line);
if(index!=-1){
printf("%s\n",n1[index].f);
}else{
printf("what?\n");
}
}else{
index = search2(line);
if(index!=-1){
int len = strlen(n2[index].c);
int i = 1;
for(;i<len-1;i++){
v[i-1] = n2[index].c[i];
}
v[i-1] = '\0';
printf("%s\n",v);
}else{
printf("what?\n");
}
}
}
}
本文介绍了一个C语言实现的自定义HashMap数据结构,用于高效地进行键值对查询。通过使用两个独立的HashMap,分别以键和值作为索引,实现了双向查找功能。文章详细解释了数据结构的设计思路,包括节点结构、哈希函数和搜索算法,并提供了完整的代码示例。

699

被折叠的 条评论
为什么被折叠?



