Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 从10亿个整数中找出与给定数字仅相差3位以内的所有数字_Algorithm - Fatal编程技术网

Algorithm 从10亿个整数中找出与给定数字仅相差3位以内的所有数字

Algorithm 从10亿个整数中找出与给定数字仅相差3位以内的所有数字,algorithm,Algorithm,这是我在一次采访中听到的一个问题。 假设您有10亿个整数,每个整数由64位表示。现在给你任意一个整数m,如何在文件中找到一个与给定数字相差不到3位的数字,可以是0位,1位,2位,或O1时间内的3位?有人能给我一些线索吗 您正在搜索的数字非常少,大约为64^3。我的建议是——一旦你得到了这个数字,计算出所有与之不同的数字,最多3位,然后把它们放在一个哈希表中。然后迭代输入,并检查每个输入的数字是否在哈希表中。这种方法将具有预期的复杂性,其中n是输入值的数量 该算法具有下限Om。你别无选择,只能强行

这是我在一次采访中听到的一个问题。
假设您有10亿个整数,每个整数由64位表示。现在给你任意一个整数m,如何在文件中找到一个与给定数字相差不到3位的数字,可以是0位,1位,2位,或O1时间内的3位?有人能给我一些线索吗

您正在搜索的数字非常少,大约为64^3。我的建议是——一旦你得到了这个数字,计算出所有与之不同的数字,最多3位,然后把它们放在一个哈希表中。然后迭代输入,并检查每个输入的数字是否在哈希表中。这种方法将具有预期的复杂性,其中n是输入值的数量

该算法具有下限Om。你别无选择,只能强行列出所有数字,并将它们与你的数字进行比较

您可以通过x和y的不同位数进行比较,如下所示:

z = x ^ y
result = count_number_one_bits(z)
如果给您提供了数字A和数字x的列表,则最终代码为:

for y in A:
  z = x ^ y
  test = count_number_one_bits(z)
  if test <= 3:
    yield y
应该给你一个接一个的数字,然后给你数字y。您可以仅使用内部循环进行检查:

z = x ^ y
test = count_number_one_bits(z)
if test <= 3:
  yield y

我有另一个可以减少搜索空间的预处理方法:对于每个整数,计算1位的数量。根据该数字对它们进行排序,并保留64个索引,每个索引指向第一个数字,其中包含64个1位、63个1位等等。。如果使用某种自定义比较运算符就地排序,则可以使用快速排序完成此预处理,而不需要额外的空间

现在,当您得到整数m时,对1位进行计数,并仅在具有n-3到n+3个1位的搜索空间中进行迭代。在这方面,您可以应用@Riko的解决方案

假设您处理的是均匀分布,这将使您的搜索空间减少到7/64倍。当然,您有预处理,这将在logn上进行,但当您有多个查找时,这将得到回报

编辑: 基于@andrewjs的评论,我想强调一下比快速排序方法更好的其他数据结构

只需计算位的数量,并将数字放入64个存储桶中。一种散列映射方法。只需要在时间上打开,但可能需要更多内存,具体取决于初始数据结构。与快速排序方法具有相同的查找时间

执行铲斗进近,但移除重复项。将比简单的bucket解决方案慢,因为您必须在bucket内对每个新元素进行比较,但如果您可以删除大量重复项,则可能会提高搜索速度



位可以在64位中的任何位置吗?现在给你一个整数m,如何在文件中找到与给定数字不同的数字-你只有一个数字m或几个m数字要检查吗?是的,没关系,伙计,我在这里犯了一些错误,你只得到一个int@Hexinwei我在这里犯了一些错误-然后编辑这个问题。显然,它不起作用,假设每次我给你一个新的数字,你总是需要遍历文件中的所有数字。我想找到一个能在O1中完成这项任务的算法,你怎么能在O1中解决它,伙计。谢谢你指出这一点。您只需执行循环中的一部分。检查编辑:@Hexinwei请在您的问题中添加更多详细信息,这样您就有了不止一个查询,而不仅仅是一个数字m?Xor新的带有??输入文件中的每一个数字或我错了?O64^3确实是O1:D祝你好运,迭代大小为3的所有子集,然后你将不得不对其中的每一个进行xor运算。这不好,伙计,bruteforce是一种方法,但不是很好,检查它。我不是建议任何暴力,我也很确定这是你在性能方面能做的最好的。暴力和你的暴力一样多,因为两者都必须遍历整个列表,都在复杂性上屈服。尽管如此,哈希运算使事情复杂化了很多,更不用说找到那些64^3的数字了!另一件事64^3是262144,这意味着它实际上不是一个常数。Ivaylo Strandjev的解决方案可以与预排序和可能的搜索空间修剪相结合。然后,您可以进行二进制搜索,以在列表中找到适合您的号码的位置,并在该位置的左右两侧进行搜索。在使用log n进行初始排序之后,您可以很快找到解决方案,即使用log n进行二进制搜索,然后进行最大64^3次的常量查找。上次我检查时,我只有4gb ram:不确定如何对列表进行二进制搜索您的建议是按1位进行排序。将有大量相等数字的比较。您可以将数字拆分为64个不同的存储桶,而不是进行排序,这些存储桶内部不进行排序。执行此分区将打开。这是正确的。这基本上是时间和空间的折衷,因为巴克
解决方案可能需要一些额外的内存,具体取决于输入的数据结构。使用大小为O2^32的位图,并将所有数字存储在位图中如何。当一个测试号出现时,你只需计算所有可能的数字C64,3,例如,通过反转测试号中的三个位,然后对照位图检查/oops,错误在这里,你需要大小为2^64的位图,我仍然认为哈希是解决这类问题的最佳方法