由百度的ip攻击面试题拓展的散列表(Hash table)

来源:互联网 发布:中医人工智能系统app 编辑:程序博客网 时间:2024/05/16 15:05

首先引入百度08年的一个面试题。

给你1亿个ip地址和每个ip访问的时间(00:00:00=<时间<=23:59:59,并且已经按照时间排好序了),然后给定一段时间X,定义在X内如果某IP的访问次数超过Y次,则判定该IP为攻击IP。要求输出所有攻击IP。只有一组测试用例。第一行输入IP记录数(即10万),时间X(10=<X<=120秒),次数Y(2=<Y<=100)。输出按访问的时间顺序输出,IP重复不再输出。
输入示例:(为了方便,只给出8个,意思意思)
8 10 2
10.254.82.126 00:00:39
10.85.124.135 00:00:40
10.254.82.126 00:00:44
10.254.82.126 00:00:44
10.1.82.125 00:00:45
10.85.124.135 00:00:48
10.254.82.126 00:00:48
10.254.82.126 00:00:49
输出示例:
10.254.82.126  
10.85.124.135  

 

关于这个题目的解决方法可以参考csdn的讨论帖:http://topic.csdn.net/u/20081224/16/23041dbb-b0b9-46c5-9ff7-3a4dede2a6e3.html 以及http://hi.baidu.com/%CF%FE%D0%C0%B3%BF/blog/item/25be2a8276e36aae0cf4d288.html给出的代码。

 

那么,关于这个面试题本身的解决方法到此为止,而由此引发的哈希表讨论才刚刚开始!

 

百度百科的这段话很好的描述了哈希表:

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

 

由上面一段话,再结合上面的面试题,我们可以有下面的几个认识:

1,什么情况下引入哈希表?

    对于数据量比较小的,通常情况下的数组查找或者其他查找可以解决问题,然而当数据量上升到上万,上亿时,则必须采用如哈希表这种快速的查找(或者说直接访问)的数据结构。

 

2,实现哈希表的关键是什么?

    哈希表关键是提供了一个关键码值和表中index的对应(不能说说一一对应,因为可能出现冲突!),这样就可以通过key的映射而直接访问。比如上面的面试题中,IP就是key,IP通过一个映射(函数)确定哈希表的index(当然,哈希表可以是一个由结构体组成的数组!)。另外一个关键就是要明白所谓的映射就是一个函数,因此构造一个散列函数是非常重要的。

 

3,如何避免冲突?

    这里对上面面试题解决冲突给出一个思路。hash表的 element可以设计如下

struct hash_element{
  const char *ip;
  int count;
  struct hash_element *next;
};

ip就放当前被hash的ip地址字符串的地址,count个数, next指向下一个冲突的地址。