哈希的一种用法——判断相等

来源:互联网 发布:u盘重装centos 编辑:程序博客网 时间:2024/04/28 14:19

小结来源:poj3349 & poj3274


在输入数据量比较大,时间要求比较高的情况下,判断相等可以考虑哈希的方法,比如,输入10W、100W,时间要求4000MS、7000MS,用普通方法肯定要TLE的,这时就需要hash。


首先要构造hash表,这里根据输入量来确定hash table的大小,比如poj3349中输入量最大12W,所以最坏情况每一种雪花都不相等需要12W个哈希项,所以这里设置HASH_BASE=12W以上的最小素数=120007(后面hash函数使用直接取余法)。

这里的构造相对简单,每次插入一个数据,这个数据都看成一个HashNode,并且用cur标记它是第几个HashNode。HashNode除了要有指向下一个HashNode的next指针外(如果两个HashNode哈希值相同,则映射到hash table的同一个地址处),还要有判断两个HashNode是否相等的变量,这里认为如果两个HashNode的num数组相等,就认为两个HashNode是同一片雪花。

const int HASH_BASE = 1200007;//100000*12以上的最小素数  const int NODE_NUMBER = 1200010;//node个数    int hashTable[HASH_BASE];  int cur;    struct HashNode{      int num[6];      int next;  };    HashNode node[NODE_NUMBER];    void initHashTable()  {      cur = 0;      for (int i = 0; i < HASH_BASE; i++)      {          hashTable[i] = -1;      }  }  


哈希函数:

unsigned getHash(int num[])  {      unsigned int value = 0;      for (int i = 0; i < 6; i++)      {          value += num[i];      }      return value%HASH_BASE;  }


插入数据:
void insertHashNode(int num[], unsigned value)  {      for (int i = 0; i < 6; i++)      {          node[cur].num[i] = num[i];      }      node[cur].next = hashTable[value];      hashTable[value] = cur;      cur++;  }

程序的进行是一边读数据,一边构建hash table,一边判断当前读到的数据是否与已经在hash table中的数据相等进行的.

bool searchHash(int num[])  {      unsigned value = getHash(num);      int next = hashTable[value];      while (next != -1)      {          if (compare(num, node[next].num))              return true;          next = node[next].next;      }      insertHashNode(num, value);      return false;  }  
即如果发现该数据的哈希值与其它冲突(hashTable[value]!=-1),就比较是否相等,不想等就插入到表中。


poj3247也是同样模式,最大数据有10W个,即10W行,因此不能直接枚举找最大距离,必须用Hash查找相同行,找到相同行再比较最大距离,看是否更新最大距离。


0 0
原创粉丝点击