【面试题-算法思想】如何从包含大量URL的A,B文件中找到相同的URL?

面试遇到的算法思想题,没有敲代码,只是整理并在头脑风暴后,重新叙述自己的思路。

问题

存在A,B文件内各包含1000G的URL,A文件内部的URL不重复,B文件内部的URL也不重复。内存3G,问如何找到A,B文件内相同的URL?

接着面试官在代码区直接敲出了几个例子:
A:
http://asdaasd.asdasd.asd
http://asdasdczxc.zxczxc/zxczxc
......
B:
http://asdasd.com/axzczxczxc/zxczxc
http://asdaasd.asdasd.asd  (找出的URL中包含这个)

问题可以抽象为:两个超大的字符串数组,找出所有相同的字符串。

(小声BB:绝对不能像我一样先傻傻地说能不能把http协议部分给压缩了…)

暴力法思路

取一个A文件内的URL,一段一段(不超内存)地遍历B文件内的URL,判断是否相同。

显然这种思路 太慢了,一次只能遍历一个字符串,而且完全忽略了题目大容量的条件。时间复杂度是O(n2

(小声BB:然鹅这种思路就是我当时说的…)

暴力延续(哈希思想)

延续暴力法的思想:暴力法中,我们每次仅拿到一条A文件中的URL,就去遍历一趟B文件。这种感觉像什么?

平行时空A中,某年级的学生有1000名(磁盘文件),每人多1枝铅笔,在另外一个平行时空B中,该年级对应的1000名同名学生中刚好每个人少了一枝铅笔。

已知有个时空穿梭者(内存)可以帮忙送笔,由于人数太多了,他不能一次性拿完1000枝笔送过去。这时候,他每次从A时空拿1枝铅笔,然后千里迢迢地去B时空,找到并送给那名同名学生铅笔。

不难看出来,他要来回穿梭1000 * 1000 = 1000 000 趟

So?
(虽然两只手拿的少,为什么不一次性拿多几枝笔一起送呢?)
(虽然内存小了点,为什么不一次性多捎几个URL一起比较呢?)

此时聪明的时空穿梭者想到了拿个箱子装10枝铅笔,只需要每枝铅笔记录一下是谁的。

即每枝铅笔对应一个姓名,每个URL对应一个hash值。

通过哈希集合hashset来存储一部分的A文件中的URL,在遍历B时只需判断该哈希集合是否已存在原本的URL即可。由于使用了hashset,故每次可以通过O(1)的时间复杂度就可以判断哈希集合内携带的一部分的URL。

不难看出来,由于1次取10枝铅笔,在时空A取100次铅笔就OK了,他只需要来回穿梭100 * 1000 = 100 000 趟

分治思想

上面的暴力延续只是一个常数级别的优化,但是已经有一种充分利用内存并使用哈希的思想了。

每次在B时空找对应的人,时空穿梭者累了。
“为什么拿几枝笔就要在B时空年级的全部学生中送笔呢?”
“他们怎么没有班级呢?!”
“我只需要在这个班上拿笔了,就去对应的班级找人就好了!”

于是乎,他去找了对应时空的校长,要求按姓名进行分班。比如李同学就分到李班,王同学就分到王班。
这样A时空的某个人分到了张班,那么对应的B时空的人肯定也分到了张班。

当然,文件AB可没有班级之分,我们需要拆分这两个大文件成一个个对应小文件。A文件分离出a1,a2,a3,a4…B文件分离出b1,b2,b3,b4…

我们拆分的要求是:如果B文件中b2中存在一个和A同名的URL,那么必定在小文件a2中,如果在a2里面找不到,那么就必不和A同名。

方法:假设我们分成n个小文件

对于文件A内所有的 URL 求 Hash( A-URL ) % n ,根据计算结果把遍历到的 URL 存储到 a0, a1, a2, …, an-1。使用同样的方法遍历文件 B 中的 URL,分别存储到文件 b0, b1, b2, …, bn-1 中。这样处理过后,所有可能相同的 URL 都在对应的小文件中,即 a0 对应 b0, …, an-1 对应 bn-1,不对应的小文件不可能有相同的 URL。

接着遍历拆分后的每一个小文件ai,把这个小文件的所有URL 存储到一个 HashSet 集合中。然后遍历 bi 中每个 URL,看在 HashSet 集合中是否存在,如果是共同的 URL则必定存在,可以把这个 URL 保存到一个单独的文件中。

这里有一个小问题:我们怎么确保拆分后的小文件内的所有URL都能装在内存里的HashSet呢?

这就需要我们根据题目的要求进行调整拆分的文件数量n。只需要保证拆分后的每一个小文件大小容量不超过内存的容量就行。本题中,需要满足:

1000G总文件容量 / n个小文件 < 3G内存容量

即n > 334 个文件。确保每个小文件容量小于3G。这样便于让HashSet一次性存储一个A文件的所有URL。

自此,时空穿梭者 一次性带着一个班级的铅笔,去找对应班级的人分发铅笔。

最后的思维导图
在这里插入图片描述

并行思想(后话)

(小声BB:最近学的并行计算,可惜了回顾的时候才想起来。)

时空乱流,B时空另外一个年级的学生铅笔又传到A时空对应年级的学生那里了。
“总不能每次都让我一个人去送铅笔吧?”
“让他们自己去找自己就好了吧~”

时空穿梭者教会了A年级所有的学生时空穿梭,让每个班的学生去找B时空的对应班级的自己。

为了提高效率,在划分完了小文件后,就可以创多个线程并行去寻找对应文件是否存在URL。
当然,这里的内存本来就限定死了,那就把几个文件发给别的服务器,让别的服务器帮忙跑下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

如果皮卡会coding

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

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

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

打赏作者

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

抵扣说明:

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

余额充值