哈希表的应用之基因诊断

随着生物基因测试的技术成熟,科学家们可以通过基因相似度检测,现在要对 N 个人进行测试基 因测试,通过基因检测是否为色盲。 测试色盲的基因组包含 8 位基因,编号 1 至 8。每一位基因都可以用一个字符来表示,这个字符 是’A’、‘B’、‘C’、'D’四个字符之一。 如:ABDBCBAD 通过认真观察研究,生物学家发现,有时候可能通过特定的连续几位基因,就能区分开是正常者 还是色盲者。对于色盲基因,不需要 8 位基因,只需要看其中连续的 4 位基因就可以判定是正常 者还是色盲者,这 4 位基因编号分别是:(第 2、3、4、5)。也就是说,只需要把第 2,3,4,5 这四 位连续的基因与色盲基因库的记录对比,就能判定该人是正常者还是色盲者。 假设给定的色盲基因库如下: ADBB BDDC CDBC BDBB … 请测试下列的基因是否为色盲 AADBBBAD ABDDCBAA CCDBCBAA ABDBBBAC ABDBCBAD ABDDBBAD

8979438401111 解答思路: 1. 可以直接把待测试基因的 2,3,4,5 位直接与基因库里的记录逐一对比,但如果色盲基因库很庞 大,程序执行效率很低 2. 可以使用哈希表来存储色盲基因库数据,通过哈希函数把 4 位色盲基因映射到哈希表中,大大提高检索的效

#include<stdio.h>
#include<Windows.h>
#include<stdlib.h>
#include<iostream>

#define BUCKET_SIZE 1024

using namespace std;

#define TABLESIZE 16

#define compare(a,b)	strcmp((const char*)a,(const char *)b)
#define hash_func		SDBMHash

typedef struct _NodeList{

	void* key;
	void *date;
	_NodeList *next; 

}ListNode,NodeList;

typedef ListNode* List;
typedef NodeList* elem;

 

typedef struct _HashTable{
	int tableSize;
	List *thelist;

}HashTable;

unsigned int SDBMHash(void *key){
	
	unsigned int hash = 0;
	char *str = (char*)key;

	while(*str){
		
		hash = (*str++)+(hash<<6)+(hash<<16)-hash;
	
	
	}

	return (hash&0x7FFFFFFF);

}

//哈希函数
int Hash(int tablesize,void* key){

	//return (key%tablesize);
	return hash_func(key)%tablesize;
}

//初始化哈希链表
HashTable *initHash(HashTable *&Hash,int tablesize){
	
	//初始化哈希桶
	Hash = (HashTable*)malloc(sizeof(HashTable));

	if(!Hash){
	
	printf("error!\n");
	return NULL;
	}

	//给索引指针分配内存
	if(tablesize<0){
		tablesize = TABLESIZE;
	}

	Hash->tableSize = tablesize;

	Hash->thelist = (List*)malloc(sizeof(List)*tablesize);

	if(!Hash->thelist){
		
		printf("error malloc!\n");
		free(Hash);
		//return ;
	}

	for(int i=0;i<tablesize;i++){
		//给每个哈希数组指针分配头节点的堆内存
		
		Hash->thelist[i] = (ListNode*)malloc(sizeof(ListNode));
		
		if(!Hash->thelist[i]){
			
			//释放内存
			printf("error malloc!\n");
			free(Hash->thelist);
			free(Hash);

		}else{
			
			memset(Hash->thelist[i],0,sizeof(NodeList));
		}	
	}
	return Hash;
}

//通过key查找元素
elem find(HashTable *&H,void* key){

	if(!H) return NULL;

	//找到索引下标
	int i =0;
	i= Hash(H->tableSize,key);
	
	List e = H->thelist[i]->next;

	while(e!=NULL&&compare(e->key,key)){
		
		e = e->next; 

	}

	//要么成功找到key,要么key不存在
	return e;

}

//插入元素
bool insertHash(HashTable *H,void* key,void *value){
	//
	//if(!H) return false;
	

	//通过键值找到元素
	elem e = find(H,key);
	elem tmp = NULL;
	elem L = NULL;
	//tmp可能存在也可能不存在,当e不存在时
	//e不存在
	if(!e){
	
	//	tmp = (elem)malloc(sizeof(elem));

		tmp = (elem)malloc(sizeof(NodeList));

		if(tmp==NULL){
		
			printf("eroor malloc!\n");
			return false;
		}

			L = H->thelist[Hash(H->tableSize,key)];	//通过key的索引找出相应的位置

			tmp->date = value;
			tmp->key = key;
			tmp->next = L->next;
			L->next = tmp;

		

	}else{
		printf("the key has been exit!\n");
	}


}

//删除元素
bool deleteElem(HashTable *H,void* key){
	//

	//找元素
	elem last = NULL;
	elem e = NULL;

	//elem e = find(H,key);//找到相应的索引位?????我在干嘛
	List L = H->thelist[Hash(H->tableSize,key)];

	last = L;
	e = L->next;
	while(e!=NULL&&compare(e->key,key)){
	
		last = e;
		e = e->next;
	}

	//如果找到了这个L
	if(e){
		//直接把它跳过
		last->next = e->next;
		delete(e);
		return true;
	
	}
	
	return false;

}

void *Retrive(elem e){
	//获取表中的元素
	return e!=NULL?e->date:NULL;//e存在就返回他自己的值否则就返回为空

}
//销毁哈希表
void destoyedHash(HashTable *&H){

	elem e = NULL;
	elem L = NULL;
	elem cur = NULL;

	for(int i=0;i<H->tableSize;i++){
		
		L = H->thelist[i];
		cur = L->next;
		while(cur!=NULL){
			elem tmp = cur;
			cur = tmp->next;
			free(tmp);
			//cur = cur->next;
		
		}
		free(L);
	}

	free(H->thelist);
	free(H);
	H = NULL;
}

#include"Hash.h"
#include<string.h>
#include<stdlib.h>


int main(){
	char *elems[]={"BDBB","DBBB","DBCC","ASDS"};

	char *tester = "ABDBBBAC";

	char cur[5]={'\0'};

	int i = 0;
	
	HashTable * H = NULL;

initHash(H,BUCKET_SIZE);

	insertHash(H,elems[0],elems[0]);
	insertHash(H,elems[1],elems[1]);
	insertHash(H,elems[2],elems[2]);
	insertHash(H,elems[3],elems[3]);

	strncpy_s(cur,tester+1,4);//这个函数的意思是截取cur指针数组中元素位置从下标1开始后4个元素

	elem e = find(H,cur);

	if(e){
		
		printf("%s\n",(const char *)Retrive(e));
	}else{
	
		printf("Not found[key:%s]\n",cur);

		}


	system("pause");
	return 0;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值