虽然我同意解决方案是利用现代技术,并利用如今的廉价内存,但问题在于锻炼大脑并了解如何在给定的限制条件下解决问题。
您谈到的散列相当简单。java 解决方案可以利用引擎盖下的一些东西,这可能会掩盖实际发生的事情,所以我将首先解释解决方案,然后再解释 java 实现。
通用解决方案:
Hashing,如 SHA1、MD5 等,通过压缩输入生成一个整数。假设您只能在每行中存储前 MB 的字符。
- 您将遍历每一行,获取前 MB 的字符,然后将其传递给散列算法(例如 MD5)。
- 然后将哈希映射为键,将行号列表/数组映射为值。
- 在第一次通过后,任何匹配前 MB 字符的行都将以相同的散列结束,因此在映射中的相同列表中。
- 为了准备第二遍,您搜索地图并剔除任何仅包含一个行号的列表。
- 然后,您通过从映射中的剩余条目中编译行号来创建行号列表,这些行将是第二遍中检查的唯一行。
- 第二遍,您从行列表中的每一行中提取第二 MB 字符,将它们散列并以与第一遍相同的方式将它们放入地图中。
- 遍历映射中的条目,剔除只有一个行号的哈希条目。
- 重复第二步,但增加字符块 (MB) 以与通行号一致。
- 当你到达一个只有一个带有多个行号的散列并且该散列只有两个元素的通道时,这些行是相同的两个。
这本质上是一个树搜索。
Java 方法:Java 有一个名为 HashMap 的类,它会自动对键进行哈希处理。通过使用
HashMap<String,ArrayList<Integer>>
对于您的主地图,您只需每次调用
- map.get(mbBlock).add(lineNumber); 当然,您应该检查这是否是第一次使用此键,以免出现空指针异常。
- 每次通过后,剔除仅包含一行的条目。
- 重复剩余的行,直到你只剩下两个行号