百度笔试题1(个人整理)

http://topic.youkuaiyun.com/u/20081224/16/23041dbb-b0b9-46c5-9ff7-3a4dede2a6e3.html

1、这是今年百度的一道笔试题。给你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

 

2、偶觉得算法思想可以如下:
输入队列比如是

struct ipChain{
  char ip[16];
  char date[16];
}ipArray[100000];
在这个ipArray 维持 2个动态标记: head 初始为0  tail为的index ipArray[tail].date - ipArray[head].date <= X 并且 ipArray[tail+1].date - ipArray[head].date > X


tail - head + 1个元素 进行散列,加下每个ip count 大于Y的直接 可以输出


以后 tail++, 查看先加入的元素是否 使 ipArray[tail].date - ipArray[head].date > x, 大于 head++, 散列表中其count--,一旦为0,删除之。然后 将新加入的ipArray[tail] 加入散列表 查看是否 count > Y


这样的话 算法 应该比 On)差不了多少。

 

3、能把哈希函数告诉吗?

就是把IP地址散列到10万的数以内,我是这样做的

例如:192.168.0.1

hash = (192 × 192 % 100000 + 168 × 168% 100000 + 0 × 0% 100000 + (1 * 1) % 100000) % 100000

有冲突就向后找空位

但是效率不高

求一个效率高的哈希函数

 

4、你自己可以根据 X的大小来选取一个平均的 hash 表长度哈

比如 x = 60(秒)(平均值)

 

1/60/24 * 1亿 = 7万左右

 

长度选取 10万应该挺合理的。

 

hash那就更简单了  IP 0.0.0.0 正好对应 4* 8(bits) = 32位(1int

写个函数 int ip_to_int(const char *ip);

将返回的数字 ret % 100000作为哈希数组索引

 

5、引用 8 huangzhtao 的回复:

能把哈希函数告诉吗?

就是把IP地址散列到10万的数以内,我是这样做的

例如:192.168.0.1

hash = (192 × 192 % 100000 + 168 × 168% 100000 + 0 × 0% 100000 + (1 * 1) % 100000) % 100000

有冲突就向后找空位

但是效率不高

求一个效率高的哈希函数

 

 

 

还有关于冲突 我觉得你的解决方法 不是很理想,找空位的方法万一制定x时间内 ip地址超过10万个呢?所以hash表的 element好好设计下

偶觉得可以

struct hash_element{

 

  const char *ip;

  int count;

  struct hash_element *next;

};

 

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

 

这样  hash_elemnt[100000];的一个hash表应该能搞定 

 

6、引用 13 fisher_047 的回复:

引用 9 threeleafzerg007 的回复:

你自己可以根据 X的大小来选取一个平均的 hash 表长度哈

比如 x = 60(秒)(平均值)

 

1/60/24 * 1亿 = 7万左右

 

长度选取 10万应该挺合理的。

 

hash那就更简单了  IP 0.0.0.0 正好对应 4* 8(bits) = 32位(1int

写个函数 int ip_to_int(const char *ip);

将返回的数字 ret % 100000作为哈希数组索引

 

 

我没太理解9楼的将IP转换成整数的方法,比如说192.0.0.1转换后是1920

 

 

 

const char *ip = "127.0.0.1";

int a1,a2,a3,a4,result = 0;

sscanf(ip,"%d.%d.%d.%d",&a1,&a2,&a3,&a4);

result |= a1 < < 24;

result |= a2 < < 16;

result |= a3 < < 8;

result |= a4;

 

7、由于条件上y <100,所以可以用byte数组散列

ip正好可以转成uint32,这样需要内存:

(2^32)b=4G Byte!!

如果就这么回答完毕的话估计是没分了.

 

可以考虑用链地址法来散列

只散列ip的前3.

另外,多用位运算估计就可以了.

 

ip的哈希的问题解决了,然后就可以滚动扫描了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cyf31

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值