c语言键值配对——(key, value)

看一个C++项目时,其中解析配置文的部分引发了我的思考。
配置文件问普通字符文件,内容都是类似 如下:
ipaddr=127.0.0.1
port=888
logfile=log
C++对此配置文件解析字符,按每次处理一行,以”=”作为分隔符将每行分成两个字符串作为(key,value)插入map 变量,举个例子
以ipaddr=127.0.0.1为例:

std::map<std::string, std::string> config_map;
//key,value = “ipaddr","127.0.0.1"
config_map..insert(std::make_pair("ipaddr", "127.0.0.1");

这个提取配置信息作为键值对 在C++中很容易实现,但是在C项目中又该如何实现呢,好像没有直接以字符串作为索引的数组,实现方式需要特殊处理。
我想到的是哈希表,这个东西类似于数组,但是索引值是以 字符串计算而来,关于哈希值得计算公式其实很简单,就是对字符串进行一系列操作。
网上有个网友写了一篇很不错的关于哈希表的文章:
https://blog.csdn.net/txl199106/article/details/40184965
其中对于哈希表的链地址法实现Hash写的非常好,链地址能在一定程度上对键冲突进行处理,如果键冲突太频繁,获取就要考虑另一种方式实现了,但是对于今天的主题,链地址hash表已经足够,并且简单。
现附上那位网友的源码,后面我会稍微修改一下,来演示键值对冲突:
代码来源
https://blog.csdn.net/txl199106/article/details/40184965

#include <string.h>
#include <stdio.h>
#include <stdlib.h>typedef struct _node{char *name;char *desc;struct _node *next;
}node;#define HASHSIZE 101
static node* hashtab[HASHSIZE];
void inithashtab(){int i;for(i=0;i<HASHSIZE;i++)hashtab[i]=NULL;
}unsigned int hash(char *s){unsigned int h=0;for(;*s;s++)h=*s+h*31;return h%HASHSIZE;
}node* lookup(char *n){unsigned int hi=hash(n);node* np=hashtab[hi];for(;np!=NULL;np=np->next){if(!strcmp(np->name,n))return np;}return NULL;
}char* m_strdup(char *o){int l=strlen(o)+1;char *ns=(char*)malloc(l*sizeof(char));strcpy(ns,o);if(ns==NULL)return NULL;elsereturn ns;
}char* get(char* name){node* n=lookup(name);if(n==NULL)return NULL;elsereturn n->desc;
}int install(char* name,char* desc){unsigned int hi;node* np;if((np=lookup(name))==NULL){hi=hash(name);np=(node*)malloc(sizeof(node));if(np==NULL)return 0;np->name=m_strdup(name);if(np->name==NULL) return 0;np->next=hashtab[hi];hashtab[hi]=np;}elsefree(np->desc);np->desc=m_strdup(desc);if(np->desc==NULL) return 0;return 1;
}/* A pretty useless but good debugging function,
which simply displays the hashtable in (key.value) pairs
*/void displaytable(){int i;node *t;for(i=0;i<HASHSIZE;i++){if(hashtab[i]==NULL)printf("()");else{t=hashtab[i];printf("(");for(;t!=NULL;t=t->next)printf("(%s.%s) ",t->name,t->desc);printf(".)\n");}}
}void cleanup(){int i;node *np,*t;for(i=0;i<HASHSIZE;i++){if(hashtab[i]!=NULL){np=hashtab[i];while(np!=NULL){t=np->next;free(np->name);free(np->desc);free(np);np=t;}}}
}main(){int i;char* names[]={"name","address","phone","k101","k110"};char* descs[]={"Sourav","Sinagor","26300788","Value1","Value2"};inithashtab();
//增加部分--------------------------打印hash_table_index   for(i = 0; i < 5; i++){unsigned int hi=hash(names[i]);printf("%s--hash_table_index=%d\n", names[i], hi);}
//---------------------------------------打印hash_table_indexfor(i=0;i<5;i++)install(names[i],descs[i]);printf("Done\n");printf("If we didnt do anything wrong..""we should see %s\n",get("k110"));install("phone","9433120451");printf("Again if we go right, we have %s and %s\n",get("k101"),get("phone"));displaytable();cleanup();return 0;
}

在此代码中,我添加了打印 字符串 对应的hash值

//增加部分--------------------------打印hash_table_index   for(i = 0; i < 5; i++){unsigned int hi=hash(names[i]);printf("%s--hash_table_index=%d\n", names[i], hi);}
//---------------------------------------打印hash_table_index

输出信息

可以看见,不同字符串获得hash值不一样,目前还没有键冲突,那么每个字符串在哈希表(static node* hashtab[HASHSIZE])中的索引便知道了, 打印信息很直白,结合源码很容易看懂。
下面来模拟键冲突的情况,其实要想两个不同的字符串对应的hash值相同,即键冲突,这样的两个字符串很难找到,不妨修改hash值的计算方式,给定一个固定值,修改如下代码:

unsigned int hash(char *s){unsigned int h=0;/**for(;*s;s++)h=*s+h*31;**/return h%HASHSIZE;
}

让其获得的hash值都为0,所以不管怎样都会出现hash值相同,即键冲突
输出信息如下:

所有的键值对都在hash表的第一项中,冲突键使用单链表连接起来了,具体是在插入新字符串键时先查找已有hash表中是否存在,如果键相等再比较字符串是否相等,见下:

node* lookup(char *n){unsigned int hi=hash(n);node* np=hashtab[hi];for(;np!=NULL;np=np->next){if(!strcmp(np->name,n))return np;}return NULL;
}

如果字符串相等,返回已有的键值对,覆盖对应的值,如果查找不存在,申请新的空间,从链表头部插入新键值对。
在C语言中链式哈希表能实现类似 C++ 中map 的键值对功能,有这个需求的可以参考以上源码内容。

hash表--c语言 字符串键值配对——(key, value)相关推荐

  1. cockroachdb mysql_CockroachDB学习笔记——[译]CockroachDB中的SQL:映射表中数据到键值存储...

    CockroachDB学习笔记--[译]CockroachDB中的SQL:映射表中数据到键值存储 原文标题:SQL in CockroachDB: Mapping Table Data to Key- ...

  2. C/C++注册表【4】键值的获取,设置,删除,枚举

    C/C++注册表[4]键值的获取,设置,删除,枚举 1.键值的获取: LONG WINAPI RegQueryValueEx(HKEY hKey, //一个已打开项的句柄,或者指定一个标准项名LPCT ...

  3. 【jQuery - serializeArray 序列化表单值并转为键值对】

    原文找不到了,先挂原创.原作者看到,请联系我,我改为转载. /*** 序列化表单值并转为键值对*/ function getFormJson(form) { var o = {}; var a = $ ...

  4. 读取注册表REG_DWORD类型的键值

    读取注册表REG_DWORD类型的键值: DWORD dwRet = 0;  HKEY hKey;  if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SYSTEM// ...

  5. 注册表 Run、RunOnce 键值解析

    注册表 Run.RunOnce 键值解析 绝大多数使用过 Windows 操作系统的用户都不会对注册表的 Run.RunOnce 键值感到陌生,但你真的了解所有这些键值的细节吗?让我们具体说来. 本文 ...

  6. 安卓 蓝牙遥控器键值配对 kl文件

    场景:厂商送过来的蓝牙遥控器有可能linux上不对应,例如蓝牙的source 被识别为F1键,这时需要重新配置kl kl知识参考 https://www.jianshu.com/p/1b0ae800b ...

  7. 键值的 key 和 value 允许为null吗

       总结: HashMap对象的key.value值均可为null. HahTable对象的key.value值均不可为null.        两者的的key值均不能重复,若添加key相同的键值对 ...

  8. c语言字符串碱基互补配对,C++ 6.0 配对碱基链 自己编的程序输出总是有问题 求解...

    C++ 6.0 配对碱基链 自己编的程序输出总是有问题 求解0 脱氧核糖核酸(DNA)由两条互补的碱基链以双螺旋的方式结合而成.而构成DNA的碱基共有4种,分别为腺瞟呤(A).鸟嘌呤(G).胸腺嘧啶( ...

  9. c语言字符串碱基互补配对,碱基互补配对原则

    碱基互补配对原则: 根据碱基互补配对的原则,一条链上的A一定等于互补链上的T:一条链上的G一定等于互补链上的C,反之如此.因此,可推知多条用于碱基计算的规律. 规律一:在一个双链DNA分子中,A=T. ...

最新文章

  1. 对话中国农民丰收节交易会 广东成立天然富硒转化联合体
  2. java怎么设置多个输入_Java中从键盘输入多个整数的方法
  3. 人类为什么没有尾巴?这个跳跃基因抹去了人类的尾巴,并带来了额外风险
  4. 怎么取消XP粘滞键(StickyKeys)
  5. JetBrains系列WebStorm等中文输入法无法跟随光标的问题的解决办法
  6. Angular CLI: 全局脚本
  7. xp_cmdshell 用法
  8. 电信中兴B860AV2.1-T_线刷固件包
  9. oracle磁带库清洁带标签,LTO-1/2/3/4/5/6/7/8 Ultrium数据磁带 清洗带 清洁带 磁带标签批发...
  10. java获取大写字母_获取中文大写首字母java实现
  11. 10款实用苹果Siri快捷指令分享
  12. EBS 表 Mtl_Material_Transactions及相关表说明
  13. 江苏工匠杯easyphp
  14. oracle账集和账薄,转载-Oracle R12 总账与子账的关系
  15. 涉密计算机不得接入 网络,任何组织和个人都不得将涉密计算机、涉密存储设备接入互联网或其他公共信息网络 - 作业在线问答...
  16. 信息学奥赛一本通 1386:打击犯罪(black)
  17. PADS学习之路09-PADS LOGIC创建原理图工程文件
  18. 主动降噪耳机那些事儿(一)
  19. C# 枚举高级用法之Description
  20. d2lzh_pytorch

热门文章

  1. php gridview,yii2-GridView在开发中常用的功能及技巧总结
  2. 北京林业大学信息学院软件工程研究生专业课初试总结
  3. PJSIP协议栈在Linux下通信测试
  4. stm8程序无法写入c语言,STM8问题汇总
  5. 【python+Selenium】Selenium使用步骤解析
  6. 休闲服务行业:贝泰妮,药妆明珠,引领国潮(20210103).PDF
  7. 自己动手合成喜欢的编程字体
  8. python编写人工智能-用Python写一个中国象棋AI?
  9. centeros安装gitlab
  10. 7星彩随机N注选号程序