用C语言写一个身份证识别省区!

qq_38241541 2017-06-19 12:14:23
这个是保存6位省区的编码txt文件,
现在就是不知道怎么把这个内容,每行信息形成hash表,怎么查找
typedef struct _hash_map_t {
size_t size;
listnode_t** key;
listnode_t** value;
} hash_map_t;
这是哈希的结构体
struct _listnode_t {
struct _listnode_t *next;

union {
void* data;
struct _list_t *list;
const char *str;
long key;
}nodeData;
};
typedef struct _listnode_t listnode_t;
这是结点的
struct _list_t {
size_t size; /* 节点数量 /
listnode_t *head; /链表头结点指针*/
listnode_t tail; /链表尾结点指针*/
};
typedef struct _list_t list_t;
这是链表的
这是老师给的代码,我不知道为什么hash结构体里面二级指针value是什么功能,能不能解释下这个到底怎么形成hash表,然后查找对应省区,输出对应省区字符串?跪求各位大神帮忙
这是hashmap.C
/*
* hashMap.c
* 通用散列表的实现
* 将键-值(key-value)对存入散列表,键(key)必须为空值结束的字符串,值(value)可以为任意类型的数据
*/
#include "hashMap.h"
#include "list.c"

typedef struct _hash_map_t {
size_t size;
listnode_t** key;
listnode_t** value;
} hash_map_t;

/* Hash a string, return a hash key */
static ulong hash_string(const char *s, int len) {
ulong h = 0;
int i = 0;
assert(s);
if (len < 0)
len = (s ? (int) strlen(s) : 0);
while (i++ < len) {
h = 17 * h + *s++;
}
return h;
}

static void _free_map_key(listnode_t* node) {
listnode_t *old;
while (node) {
old = node;
node = node->next;

free(old->nodeData.data);
free(old);
}
}

static void _free_map_value(listnode_t* node, pfcb_hmap_value_free pfunc) {
listnode_t *old;
while (node) {
old = node;
node = node->next;

if (pfunc)
(*pfunc)(old->nodeData.data);
free(old);
}
}

/*=============================================================================
公用函数
=============================================================================*/

/* 使用前创建 */
void hashMapCreate(HashMap *hashMap, int size) {
(*hashMap) = (hash_map_t*) malloc(sizeof (hash_map_t));
(*hashMap)->size = size;
(*hashMap)->key = (listnode_t**) calloc(size, sizeof (listnode_t*));
(*hashMap)->value = (listnode_t**) calloc(size, sizeof (listnode_t*));
}


/* 用完后清除 */
extern void hashMapDestroy(HashMap hashMap, pfcb_hmap_value_free pfunc) {
/*请实现该函数*/



}

/* 向散列表插入键-值对(key-value),值为调用程序分配的内存指针 */
void hashMapInsert(HashMap hashMap, const char* key, int key_len, void* value) {
/*请实现该函数*/
//hashMap->size=key_len;
// hashMap.key=key;
// hashMap.value=value;


}

/* 用指定的字符串(键)在散列表中查找对应的值 */
void* hashMapSearch(HashMap hashMap, const char *key) {
/*请实现该函数*/
//hashMap.key


}

这是hashmap.h
/* 
* File: hashMap.h
* Author: zhangtaihong
*
* Created on 2013年8月7日, 下午12:24
*/

#ifndef HASHMAP_H
#define HASHMAP_H

#ifdef __cplusplus
extern "C" {
#endif

#include "unistd.h"

/* 静态散列表主桶的数量 */
#define HASHMAP_SIZE 1024

/* 指向_hash_map_t结构的不透明指针,隐藏_hash_map_t的实现细节 */
typedef struct _hash_map_t* HashMap;

typedef void(*pfcb_hmap_value_free)(void* value);

/* 调用程序实现的清除值函数的例子
void my_hmap_free_value(void* pv)
{
free(pv);
}*/


/* 使用前先创建,如:
* HashMap hashMap;
* hashMapCreate(&hashMap, HASHMAP_SIZE);
* assert (hashMap); //如果hashMap==NULL,说明内存不足
* void* mydata=malloc(n);
* hashMapInsert(hm, "shanghai", -1, mydata);
...
* 程序结束前清除散列表
* hashMapDestroy(hashMap, my_hmap_free_value);
*/
extern void hashMapCreate(HashMap *hashMap, int size);

/* 清除散列表 */
extern void hashMapDestroy(HashMap hashMap, pfcb_hmap_value_free pfunc);

/* 向散列表插入键-值对(key-value),值为调用程序分配的内存指针 */
extern void hashMapInsert(HashMap hashMap, const char* key, int key_len/* -1 使用strlen函数 */, void* value);

/* 用指定的可以字符串在散列表中查找键对应的值 */
extern void* hashMapSearch(HashMap hashMap, const char *key);


#ifdef __cplusplus
}
#endif

#endif /* HASHMAP_H */

这是list.h
/* 
* File: list.h
* Author: zhangtaihong
* 通用顺序链表及节点结构 -- 可以存储任意类型的数据
* Created on 2013年8月7日, 下午12:28
*/

#ifndef LIST_H
#define LIST_H

#ifdef __cplusplus
extern "C" {
#endif

#include "unistd.h"

struct _listnode_t {
struct _listnode_t *next;

union {
void* data;
struct _list_t *list;
const char *str;
long key;
}nodeData;
};
typedef struct _listnode_t listnode_t;

struct _list_t {
size_t size; /* 节点数量 */
listnode_t *head; /*链表头结点指针*/
listnode_t *tail; /*链表尾结点指针*/
};
typedef struct _list_t list_t;

/* list_destroy()要调用的回调函数的声明, 若为NULL,表示不用回调函数 */
typedef void(*pfcb_list_node_free)(listnode_t* node);

/* 被调用程序实现的节点数据清理函数的例子
void myListNodeFree(listnode_t *node)
{
free(node->nodeData.data);
}*/

/* 向链表添加一个节点 */
extern void listAppendNode(list_t *in_list, listnode_t *in_node);

/* 删除链表的第一个节点,返回新的链表 */
extern listnode_t* listRemoveHead(list_t *in_list);

/* 删除链表中的所有节点,但链表本身依然保留 */
extern void listRemoveAll(list_t *in_list, pfcb_list_node_free pfunc /* NULL for no use or a key node */);

/* 返回链表的一个拷贝 */
extern list_t* listCopy(list_t in_list);

/* 合并两个链表,将second合并到first,不清除second */
extern void list_concat(list_t *first, list_t *second);

/* 创建一个新节点,不为输入的node_data分配内存 */
extern listnode_t* listNodeCreate(void* node_data);

/* 创建一个新节点,整型键值 */
extern listnode_t* listKeyCreate(long node_key);

/* 在队内存创建一个空链表 */
extern list_t* listCreate();

/* 从对内存中清除一个链表
* 被调用程序负责清理节点数据,即该函数会调用节点清理函数(pfunc)
*/
extern void listDestroy(list_t *in_list, pfcb_list_node_free pfunc /* NULL for no use or a key node */);

/* 获取链表中节点的个数 */
extern size_t listSize(const list_t* in_list);

/* 按索引下标获取节点,索引下标从0开始,下标0的节点为头节点 */
extern listnode_t* listNodeAt(const list_t* in_list, int index);
#ifdef __cplusplus
}
#endif

#endif /* LIST_H */
...全文
496 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhu_meng_ 2017-06-24
  • 打赏
  • 举报
回复
这个用C++的容器MAP容器很简单的。可能故意要用C实现吧。还是再好好看下hash的C语言实现吧。感觉你这个好麻烦。
内存现在不缺,用六位的二维数组就能很简单的实现。第一个成员为数字,后面的字符串代表那个省区。直接用省份证的这个值直接索引出来。
yi19861209 2017-06-24
  • 打赏
  • 举报
回复
赵4老师 2017-06-19
  • 打赏
  • 举报
回复
为什么不使用stl的map呢?
LubinLew 2017-06-19
  • 打赏
  • 举报
回复
仅供参考

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

/* ------------------结构体定义------------------ */
typedef struct _hashBucket_t {
	char* key;
	size_t key_len;
	char* data;
	size_t data_len;
	struct _hashBucket_t *next;
}  hashBucket_t;

typedef struct _hashMap_t {
	size_t hash_bits;
	size_t bucket_num;
	hashBucket_t bucket[0];
} hashMap_t;

/* -----------------hashmap API ------------------ */
/* count: 预计有多少条数据 */
hashMap_t* hashMapCreate(unsigned long count);
void hashMapDestroy(hashMap_t* map);
void hashMapInsert(hashMap_t* map, void* key, size_t key_len, void* data, size_t data_len);
int hashMapSearch(hashMap_t*   map, void* key, size_t key_len, void** data, size_t* data_len);


/* ------------------demo------------------------ */
int main(void)
{
	hashMap_t* map = NULL;
	char* data = NULL;
	size_t data_len = 0;
	int ret;

	map = hashMapCreate(1000);

	hashMapInsert(map, "1+1=", 4, "2", 1);
	hashMapInsert(map, "1+2=", 4, "3", 1);
	hashMapInsert(map, "1+3=", 4, "4", 1);
	hashMapInsert(map, "1+4=", 4, "5", 1);
	hashMapInsert(map, "1+5=", 4, "6", 1);
	hashMapInsert(map, "1+6=", 4, "7", 1);
	hashMapInsert(map, "1+7=", 4, "8", 1);
	hashMapInsert(map, "1+8=", 4, "9", 1);
	hashMapInsert(map, "Hello", -1, "World", -1);

	ret = hashMapSearch(map, "Hello", -1, (void**)&data, &data_len);
	if (ret == 1) {
		printf("%s(len=%zx)\n", data, data_len);
	}
	else {
		printf("not found\n");
	}

	hashMapDestroy(map);

}

hashMap_t* hashMapCreate(unsigned long count)
{
	int i = 0;
	size_t bucket_num = 1;
	size_t hash_bits = 0;
	hashMap_t* map = NULL;

	while (1) {
		bucket_num *= 2;
		hash_bits++;
		if (bucket_num >= count) {
			break;
		}
	}
	
	map = (hashMap_t*)calloc(1, sizeof(hashMap_t) + \
	sizeof(hashBucket_t) * bucket_num);
	map->bucket_num = bucket_num;
	map->hash_bits = hash_bits;

	return map;
}

void hashMapDestroy(hashMap_t* map)
{
	int i;
	hashBucket_t* bucket;	
	hashBucket_t* tmp;
	
	for (i = 0; i < map->bucket_num; i++) {
		bucket = &map->bucket[i];
		if (bucket->key_len == 0) {
			continue;
		}
		free(bucket->data);
		free(bucket->key);

		bucket = bucket->next;
		while (bucket != NULL) {
			free(bucket->data);
			free(bucket->key);
			tmp = bucket;
			bucket = bucket->next;
			free(tmp);
		}
	}
	free(map);
}

static unsigned long _calcHashValue(hashMap_t* map, void* key, size_t key_len)
{
	char* ch = (char*)key;
	unsigned long seed = 131UL;
	unsigned long hash = 0UL;

	for (ch = (char*)key; ch < (char*)key + key_len; ch++) {
		hash = hash * seed + (*ch);
	}

	hash &= (~0UL >> (sizeof(unsigned long) * 8 - map->hash_bits));
	
	return hash;
}

void hashMapInsert(hashMap_t*      map, void* key, size_t key_len, void* data, size_t data_len)
{
	unsigned long hash = _calcHashValue(map, key, key_len);
	hashBucket_t* bucket = &map->bucket[hash];

	if (key_len == -1) {
		key_len = strlen((char*)key);
	}
	if (data_len == -1) {
		data_len = strlen((char*)data);
	}

	if (bucket->key_len) {
		while (bucket->next != NULL) {
			bucket = bucket->next;
		}

		bucket->next = (hashBucket_t*)calloc(1, sizeof(hashBucket_t));
		bucket = bucket->next;
	}

	bucket->key = (char*)calloc(1, key_len + 1);
	memcpy(bucket->key, key, key_len);
	bucket->key_len = key_len;

	bucket->data = (char*)calloc(1, data_len + 1);
	memcpy(bucket->data, data, data_len);
	bucket->data_len = data_len;
}

int hashMapSearch(hashMap_t*   map, void* key, size_t key_len, void** data, size_t* data_len)
{
	unsigned long hash = _calcHashValue(map, key, key_len);
	hashBucket_t* bucket = &map->bucket[hash];

	if (key_len == -1) {
		key_len = strlen((char*)key);
	}

	while (bucket != NULL) {
		if ((key_len == bucket->key_len) && !memcmp(key, bucket->key, key_len)) {
			if (data) {
				*data = bucket->data;
			}
			if (data_len) {
				*data_len = bucket->data_len;
			}
			return 1;	
		}
		bucket = bucket->next;
	}

	return 0;
}


69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧