哈希表的企业级应用— —DNA 检测字串匹配

简介: 哈希表的企业级应用— —DNA 检测字串匹配

随着生物基因测试的技术成熟,科学家们可以通过基因相似度检测,现在要对 N 个人进行测试基 因测试,通过基因检测是否为色盲。


9926385f1e8c4fafbed4b3a573ec6fb6.png

测试色盲的基因组包含 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


解答思路:


1. 可以直接把待测试基因的 2,3,4,5 位直接与基因库里的记录逐一对比,但如果色盲基因库很庞 大,程序执行效率很低

2. 可以使用哈希表来存储色盲基因库数据,通过哈希函数把 4 位色盲基因映射到哈希表中,大大提高检索的效率.


源码实现:

hash_table.h

#pragma once
#define DEFAULT_SIZE  16
typedef struct _ListNode
{
  struct _ListNode* next;
  void* key;
  void* data;
}ListNode;
typedef ListNode* List;
typedef ListNode* Element;
typedef struct _HashTable
{
  int TableSize;
  List* Thelists;
}HashTable;
//哈希函数
int Hash(void* key, int TableSize);
//初始化
HashTable* InitHash(int TableSize);
//插入
void Insert(HashTable* HashTable, void* key, void* value);
//查找
Element Find(HashTable* HashTable, void* key);
//销毁
void Destory(HashTable* HashTable);
//提取
void* Retrieve(Element e);


hash_table.cpp

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hash_table1.h"
#define BUCKET_SIZE 1024
#define compare(a,b)  strcmp((const char*)a,(const char*)b)
#define hash_func SDBMHash
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(void* key, int TableSize)
{
  return hash_func(key) % TableSize; //先将hash_func转换为数字,再进行计算
}
HashTable* InitHash(int TableSize)
{
  int i = 0;
  HashTable* hTable = NULL;
  if (TableSize <= 0)
  {
    TableSize = DEFAULT_SIZE;
  }
  hTable = (HashTable*)malloc(sizeof(HashTable));
  if (hTable == NULL)
  {
    printf("HashTable malloc error.\n");
    return NULL;
  }
  hTable->TableSize = TableSize;
  //为Hash桶分配内存空间,其为一个指针数组
  hTable->Thelists = (List*)malloc(sizeof(List) * TableSize);
  if (hTable->Thelists == NULL)
  {
    printf("HashTable malloc error.\n");
    free(hTable);
    return NULL;
  }
  for (i = 0; i < TableSize; i++)
  {
    hTable->Thelists[i] = (ListNode*)malloc(sizeof(ListNode));
    if (hTable->Thelists[i] == NULL)
    {
      printf("HashTable malloc error.\n");
      free(hTable->Thelists);
      free(hTable);
      return NULL;
    }
    else
    {
      memset(hTable->Thelists[i], 0, sizeof(ListNode)); //为每一个hTable->Thelists[i]的数组赋值
    }
  }
  return hTable;
}
Element Find(HashTable* HashTable, void* key)
{
  int i = 0;
  List L = NULL;
  Element e = NULL;
  i = Hash(key, HashTable->TableSize);
  L = HashTable->Thelists[i];
  e = L->next;
  while (e != NULL && compare(e->key, key) != 0)
  {
    e = e->next;
  }
  return e;
}
void Insert(HashTable* HashTable, void* key, void* value)
{
  Element e = NULL, tmp = NULL;
  List L = NULL;
  e = Find(HashTable, key);
  if (e == NULL)
  {
    tmp = (Element)malloc(sizeof(ListNode));
    if (tmp == NULL)
    {
      printf("malloc error\n");
      return;
    }
    //前插
    int code = Hash(key, HashTable->TableSize);
    L = HashTable->Thelists[code];
    tmp->data = value;
    tmp->key = key;
    tmp->next = L->next;
    L->next = tmp;
  }
  else
  {
    printf("the key already exist\n");
  }
}
void Delete(HashTable* HashTable, void* key)
{
  Element e = NULL, last = NULL;
  List L = NULL;
  int i = Hash(key, HashTable->TableSize);
  L = HashTable->Thelists[i];
  last = L;
  e = L->next;
  while (e != NULL && e->key != key)
  {
    last = e;
    e = e->next;
  }
  if (e)
  {
    last->next = e->next;
    free(e);
  }
}
void* Retrieve(Element e)
{
  return e ? e->data : NULL;
}
void Destory(HashTable* HashTable)
{
  int i = 0;
  List L = NULL;
  Element cur = NULL, next = NULL;
  for (i = 0; i < HashTable->TableSize; i++)
  {
    L = HashTable->Thelists[i];
    cur = L->next;
    while (cur != NULL)
    {
      next = cur->next;
      free(cur);
      cur = next;
    }
    free(L);
  }
  free(HashTable->Thelists);
  free(HashTable);
}
int main(void)
{
  char* elems[] = { "ADBB","BDDC","CDBC","BDBB" };
  char* tester = "ABDBBBAC";
  char cur[5] = { '\0' };
  int i = 0;
  HashTable* HashTable = NULL;
  HashTable = InitHash(BUCKET_SIZE);
  Insert(HashTable, elems[0], elems[0]);
  Insert(HashTable, elems[1], elems[1]);
  Insert(HashTable, elems[2], elems[2]);
  Insert(HashTable, elems[3], elems[3]);
  strncpy_s(cur, tester + 1, 4); //ADBB'\0'
  Element e = Find(HashTable, cur);
  if (e)
  {
    printf("%s\n", (const char*)Retrieve(e));
  }
  else
  {
    printf("Node found [key:%s]\n", cur);
  }
  system("pause");
  return 0;
}


相关文章
|
10月前
|
搜索推荐 Linux Python
VET:一个基于R语言的VCF数据提取工具,支持按基因ID、物理位置、样品名称提取指定变异信息
VET:一个基于R语言的VCF数据提取工具,支持按基因ID、物理位置、样品名称提取指定变异信息
|
21天前
|
机器学习/深度学习 人工智能 API
人工智能平台PAI 操作报错合集之DSSM负采样时,输入数据不同,被哈希到同一个桶里,导致生成的embedding相同如何解决
阿里云人工智能平台PAI (Platform for Artificial Intelligence) 是阿里云推出的一套全面、易用的机器学习和深度学习平台,旨在帮助企业、开发者和数据科学家快速构建、训练、部署和管理人工智能模型。在使用阿里云人工智能平台PAI进行操作时,可能会遇到各种类型的错误。以下列举了一些常见的报错情况及其可能的原因和解决方法。
|
21天前
|
算法 C++
C++哈希表企业级运用----DNA序列的检测
C++哈希表企业级运用----DNA序列的检测
|
21天前
GEE——土地利用分类种两个矢量集合中不同列进行相减的方式(利用join进行连接处理)
GEE——土地利用分类种两个矢量集合中不同列进行相减的方式(利用join进行连接处理)
40 2
|
21天前
【代数学习题3】从零理解数域扩张与嵌入 —— 同构、商环、分裂域与同态映射
【代数学习题3】从零理解数域扩张与嵌入 —— 同构、商环、分裂域与同态映射
148 0
|
21天前
|
数据采集 安全 数据挖掘
【数据挖掘】属性及其类型和数据的统计描述四分位数等详解(图文解释 超详细)
【数据挖掘】属性及其类型和数据的统计描述四分位数等详解(图文解释 超详细)
114 0
|
6月前
|
移动开发 人工智能
马尔可夫链预测举例——钢琴销售的存贮策略
马尔可夫链预测举例——钢琴销售的存贮策略
|
存储 数据库 数据中心
你所有的数码照片都可以作为 DNA 存储吗?
你所有的数码照片都可以作为 DNA 存储吗?
|
机器学习/深度学习 自然语言处理 算法
【自然语言处理】正向、逆向、双向最长匹配算法的 切分效果与速度测评
【自然语言处理】正向、逆向、双向最长匹配算法的 切分效果与速度测评
155 0
|
vr&ar 网络架构 ice
【每日一题Day46】LC1774最接近目标价格的甜点成本 | 回溯 哈希表
当curCost已经不可能再对最终结果有影响时,即curCost>target 并且res更加接近target(剪枝1)
63 0

热门文章

最新文章