如何删除数组中出现的最长前缀?

时间:2010-10-19 08:47:00

标签: ruby arrays algorithm

我有两个数组,searchtarget。我想找到search的最长元素序列,它从search的开头开始,并且在target中也以相同的连续顺序出现。然后我想返回target的副本,删除这些元素。

以下是一些例子:

search = [4, "apple", 6, "turnip"]
target = [5, "apple", 4, "orange"]
=> [5, "apple", "orange"]           # Delete [4], the longest matching
                                    # prefix of `search`.

search = [4, "apple", 6, "turnip"]
target = [5, "apple", 4, "apple"]
=> [5, "apple"]                     # Delete [4, "apple"], the longest matching
                                    # prefix of `search`.

search = [4, "apple", 6, "turnip"]
target = [5, "apple", 6, 7]
=> [5, "apple", 6, 7]               # Nothing was matched; don't delete anything.

执行此检查的最简洁方法是什么?

4 个答案:

答案 0 :(得分:1)

如果您想要在O(m.n)中运行的简单解决方案,其中m和n是目标和搜索字符串的长度,Ni​​kita的解决方案是一个很好的解决方案。

如果需要,可以在线性时间内执行此操作,并执行一些复杂的实现。 您的问题非常类似于一般的字符串搜索问题。最有效的字符串搜索算法可以向后工作,因此他们擅长查找后缀(如果不是完全匹配)。由于您需要前缀,因此您需要先反转搜索和目标字符串。然后运行Boyer-MooreKMP字符串搜索。这些算法的通常实现只会给你完全匹配。但稍作修改,您也可以记住最长的前缀匹配。完成后,您可以返回并在另一个线性传递中删除它。

答案 1 :(得分:0)

我没有时间制定完整的解决方案,但我会说有两种方法:

  1. 使用一对外部迭代器 并行运行数组。 有平行的教程 在互联网上迭代,或 看看红宝石的副本 编程语言有一个 好的描述

  2. 或者你可以循环 搜索数组,弹出项目 目标数组,直到 目标数组为空(在这种情况下 无论你在搜索中得到什么 是你的前缀),或者你到了 搜索数组的结尾(在其中 它完全包含在 目标数组)。

  3. http://flylib.com/books/en/2.44.1.124/1/

    有一个很好的并行迭代方法

答案 2 :(得分:0)

嗯,这看起来简单而紧凑,不会影响复杂性

s_index = 0
result = target.select do |t|
  match = search[s_index] == t
  s_index += 1 if match
  !match
end

Array#select docs

欢迎改进!
此外,如果您的search数组可以包含nil个值,则需要在此处进行边框检查(s_index < search.length)。

答案 3 :(得分:0)

您可以使用类似下面的代码。但它绝对没有针对性能进行调整。

class Array
  def remove(start, length)
    length.times {delete_at start}
    self
  end
end

def remove(a,b)
  b.length.downto(1) do |len|
    index = a.each_cons(len).to_a.index b[0,len]
    return a.remove(index, len) if index
  end
  return a
end

search = [4, "apple", 6, "turnip"]
target = [5, "apple", 4, "orange"]
remove target, search