【问题标题】:Efficient algorithm for searching unsorted array搜索未排序数组的高效算法
【发布时间】:2016-09-01 15:09:17
【问题描述】:

当时发布了我的问题,我真的不清楚。在这个问题上需要帮助。

给定一个包含 100 万个值和整数 N 的 csv 文件,我必须想出一个算法来检查文件中是否存在 N,如果存在则返回 true,如果不存在则返回 false。这些值被放入一个数组中。

使用 for 循环本身将花费数小时,我需要在 5 分钟内完成此迭代。

编辑:我想出了一个二进制搜索代码。不幸的是,这花了超过 5 分钟。如何加快搜索过程?

def exist?(id)
employee_list = $employee_list
mid = employee_list.length / 2

while mid != 0 and mid+1 != employee_list.length
    a = employee_list[mid]
    if a != id 
        if a > id 
            if mid<=employee_list.length/2 
                mid = mid / 2
            elsif mid>employee_list.length/2
                mid = ((mid-(employee_list.length/2))/2) + ((employee_list.length)/2)
            end
        elsif a < id 
            if mid>=employee_list.length/2
                mid = mid + ((employee_list.length-mid)/2) 
            elsif mid<employee_list.length/2
                mid = (((employee_list.length/2) - mid)/2) + mid
            end
        end
    else 
        return true
    end
end
return false 
end

【问题讨论】:

  • 我目前所做的是进行二分搜索
  • 不能对未排序的数组进行二分查找
  • 如果您需要多次搜索数组,那么执行二进制搜索是正确的答案 - 但您必须首先对数组进行排序才能执行此操作。您能否在上面的帖子中包含您当前解决此问题的尝试?
  • "那时" – 你指的是the question你4小时前发帖吗?你仍然可以编辑它。
  • 在我看来,用 100 万个对象迭代一个数组需要几个小时。你在数组中存储什么样的对象?他们多大?您的情况如何?

标签: ruby iteration


【解决方案1】:

使用 for 循环本身将花费数小时

这不是真的。不到一秒钟。

如果你只需要做一次:

  1. 使用蛮力(循环)

如果您需要更多,那么 logN 次:

  1. 将您的数组转换为 Set/Hash
  2. 检查你的号码是否存在于哈希中

蛮力会让你付出代价O(n)

二分搜索将花费您 O(n*log(n)) 进行排序(一般情况下)+ O(log(n)) 进行搜索。

使用哈希将花费您 O(n) 来构造 Hash 并摊销 O(1) 以进行查找。

【讨论】:

  • 如果你只需要做一次,那么排序肯定会和运行include?检查一样长?....
  • @TomLord 是的 :),我一发布答案就意识到了
  • 这是否意味着对于未排序的数组,不可能搜索小于 O(n)
  • 是的,如果您有更多内核,您只能并行计算。
【解决方案2】:

这里我用一个随机整数初始化了一个包含 100 万个值的数组。并且测试值为 4。

array = Array.new(1_000_000) { rand(1_000_000_000_000) }
test_val = 494_930_039

要检查数组中是否有任何值等于测试值,只需对数组使用any? 方法即可。像这样,

array.any? {|x| x == test_val }

这将返回truefalse

基准测试结果

user CPU time                              0.050000s
system CPU time                            0.000000s
the sum of the user and system CPU times   0.050000s
the elapsed real time                      0.050704s

【讨论】:

  • 这个答案没有抓住重点。您没有解决“效率”问题,并且您的基准具有高度误导性。之所以这么“快”是因为你的大数组只包含数字0-10,所以array.any?方法平均只会检查11个值。
  • 我更新了rand函数生成0到1,000,000,000,000(不包括)的值,速度还是不错的。
  • 但仍然具有误导性,因为效率是一种方法与另一种方法的比较。对单一方法进行基准测试显示了它自己的性能,但相比之下没有显示它的效率。
  • 你仍然没有抓住重点。您还没有解决“什么是最有效的方法?”的问题,并且您的基准仍然毫无意义,因为它取决于随机数组中值 494_930_039 碰巧出现的位置,这个时间。您需要多次运行测试并获得平均结果。
  • “我需要在 5 分钟内完成此迭代”是问题的一部分,这就是我正在比较我的方法
猜你喜欢
  • 1970-01-01
  • 2012-04-26
  • 1970-01-01
  • 2020-03-20
  • 2013-11-18
  • 2014-10-24
  • 1970-01-01
  • 2015-09-26
  • 1970-01-01
相关资源
最近更新 更多