2021-05-10

简单字符串哈希表的实现

为什么去做这个?

之前接触过一些简单哈希表的实现,是用数字进行实现的,而在生活的大多数场景中,还是比较多的去使用的是字符串,那么就产生了将字符串保存入哈希表的想法,在这里使用的字符串是一些URL,在工作中,我们往往会接触到MQTT这个协议,其中发布与订阅者之间的订阅树的维护,就是使用这种解析URL以后,将其存放到对应的哈希表中。关于这一部分内容,感兴趣的小伙伴可以去看看逍遥子的mosquitto源码解析,https://blog.csdn.net/sinat_31500569/article/details/64200902?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162061160616780357298624%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=162061160616780357298624&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-10-64200902.pc_search_result_no_baidu_js&utm_term=mosquitto+%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90&spm=1018.2226.3001.4187,还有一些代码的优化,也很实用。

代码展示

头文件 

#ifndef __HASH_H__
#define __HASH_H__

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

#define HASH_TABLE_SIZE   676
#define URL_SIZE          128
#define URL_LEN           32
#define ASCII_A           161
#define FRIST_BIT         0
#define TWO_BIT           1

typedef char DataType[URL_SIZE];

typedef struct node
{
	DataType Data;
	struct node *pNext;
}LinkNode;




#endif

c文件

#include "hash.h"

//创建哈希表组
LinkNode *HashTable[HASH_TABLE_SIZE] = {0};


//寻找url二级键值
char* getKeyValue(char *url)
{
	char *new_url = NULL;
	new_url = strtok(url,"/");
	new_url = strtok(NULL,"/");	
	return new_url;
}

//将键值转化为数字键值
int getIdxValue(char *key)
{
	char valuel = 0;//键值第一个字母
	char two_valuel = 0;//键值第二个字母
	char keykey[URL_SIZE] = {0};
	int idxl = 0;
	if(NULL != key)
	{	
		strcpy(keykey,key);
		valuel = keykey[FRIST_BIT];
		two_valuel = keykey[TWO_BIT];
  		idxl = (valuel -'\0') + (two_valuel-'\0') - ASCII_A;
		return idxl;
	}
	return 0;
	
}
//将url插入哈希表
int InsertHashTable(char *url)
{

	int len = 0;
	char old_url[URL_SIZE] = {0};
	char *value = NULL;
	strcpy(old_url,url);
	char *key = getKeyValue(url);
	if(NULL == key)
	{
		return 0;
	
	}
	int idx = getIdxValue(key);
	len = strlen(key);
	value = strstr(old_url,key);
	value++;
	value += len;
	
	
	LinkNode *pInsertNode = malloc(sizeof(LinkNode));
	if(NULL == pInsertNode)
	{
		perror("fail to malloc");
		return -1;
	}
	strcpy(pInsertNode->Data,value);
	pInsertNode->pNext = NULL;

	LinkNode **ppTmp = &HashTable[idx]; 
	while(NULL != (*ppTmp))
	{
		ppTmp = &((*ppTmp)->pNext);
	}
	pInsertNode->pNext = *ppTmp;
	*ppTmp = pInsertNode;
}
//打印哈希表
void ShowHashTable()
{
	int i = 0;
	for(i = 0; i < HASH_TABLE_SIZE;i++)
	{
		if(NULL != HashTable[i])
		{
			LinkNode *pTmpNode = HashTable[i];
			while(pTmpNode != NULL)
			{
				printf("%s ",pTmpNode->Data);
				pTmpNode = pTmpNode->pNext;
			}
			printf("\n");
		}
		continue;
	}
}
//查找哈希表中是否存在该url
int FindHashTable(char *url)
{
	
	int len = 0;
	char old_url[URL_SIZE] = {0};
	char *value = NULL;
	strcpy(old_url,url);
	char *key = getKeyValue(url);
	if(NULL == key)
	{
		return 0;
	}	
	int idx = getIdxValue(key);	
	len = strlen(key);
	value = strstr(old_url,key);
	value++;
	value += len;

	LinkNode *pTmpNode = HashTable[idx];		
	while(pTmpNode != NULL)
	{	
		if(!strcmp(pTmpNode->Data,value))
		{
			printf("有该URL:%s\n",pTmpNode->Data);
			return 1;
		}
		pTmpNode = pTmpNode->pNext;
	}
	return 0;
}
//销毁哈希表
void DestroyHashTable()
{
	int i = 0;
	LinkNode *pFreeNode = NULL;
	LinkNode *pTmpNode = NULL;
	for(i = 0; i < HASH_TABLE_SIZE; i++)
	{
		pTmpNode = HashTable[i];
		while(pTmpNode != NULL)
		{
			pFreeNode = pTmpNode;
			pTmpNode = pTmpNode->pNext;
			free(pFreeNode);
		}
	}
	return;
}

int main(void)
{
	char value[URL_SIZE] ={0};
	int i = 0;
	char url[URL_LEN][URL_SIZE] ={"/ISA/Syste/device","/ISA/System/time",
						"/ISA/Syste/time/timeZ","/ISA/System/upgradeFlag",
						"/ISA/Syste/Hardwar/capabilities","/ISA/System/Software/capabilities",
						"/ISA/Syste/Vid/inputs/OSDLanguage","/ISA/System/Video/inputs/1/overlays",
						"/ISA/Event/channels/capabilities","/ISA/PTZCtrl/channels/1",
						"/ISA/Ctrl/channe/1/maxele/capabil","/ISA/Image/proportionalpan",
						"/ISA/Image/channels/1/i","/ISA/Security/sessionHear"};
	for(i = 0; i < URL_LEN;i++)
	{
		if(NULL != url[i])
		{
			InsertHashTable(url[i]);
		}
	}
	
	ShowHashTable();

	printf("请输入查找URL:\n");
	scanf("%s",value);
	if(!FindHashTable(value))
	{
		printf("没有找到这个数\n");
	}

	DestroyHashTable();
	return 0;
}

总结

这段代码主要适用于新手小白,可以更加深刻的体会哈希表的概念,在这里面我对键值做了两次处理,虽然不算是引用了哈希地图,但是还是有一点其中的思想在里面。希望和大家一起学习,有什么问题,相互讨论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值