当前位置 博文首页 > ice_elephant的博客:哈希表的应用之基因诊断

    ice_elephant的博客:哈希表的应用之基因诊断

    作者:[db:作者] 时间:2021-09-16 15:48

    随着生物基因测试的技术成熟,科学家们可以通过基因相似度检测,现在要对 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;