我有两个数组,search
和target
。我想找到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.
执行此检查的最简洁方法是什么?
答案 0 :(得分:1)
如果您想要在O(m.n)中运行的简单解决方案,其中m和n是目标和搜索字符串的长度,Nikita的解决方案是一个很好的解决方案。
如果需要,可以在线性时间内执行此操作,并执行一些复杂的实现。 您的问题非常类似于一般的字符串搜索问题。最有效的字符串搜索算法可以向后工作,因此他们擅长查找后缀(如果不是完全匹配)。由于您需要前缀,因此您需要先反转搜索和目标字符串。然后运行Boyer-Moore或KMP字符串搜索。这些算法的通常实现只会给你完全匹配。但稍作修改,您也可以记住最长的前缀匹配。完成后,您可以返回并在另一个线性传递中删除它。
答案 1 :(得分:0)
我没有时间制定完整的解决方案,但我会说有两种方法:
使用一对外部迭代器 并行运行数组。 有平行的教程 在互联网上迭代,或 看看红宝石的副本 编程语言有一个 好的描述
或者你可以循环 搜索数组,弹出项目 目标数组,直到 目标数组为空(在这种情况下 无论你在搜索中得到什么 是你的前缀),或者你到了 搜索数组的结尾(在其中 它完全包含在 目标数组)。
答案 2 :(得分:0)
嗯,这看起来简单而紧凑,不会影响复杂性
s_index = 0
result = target.select do |t|
match = search[s_index] == t
s_index += 1 if match
!match
end
欢迎改进!
此外,如果您的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