How to remove the longest prefix that appears in an array?

I have two arrays, searchand target. I want to find the longest sequence of elements searchthat starts from the beginning searchand which also appears in the same order in a row in target. Then I want to return a copy targetwith deleted items.

Here are some examples:

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.

What is the most concise way to perform this check?

+3
source share
4 answers

Nikita's solution is good if you need a simple solution that runs in O (mn), where m and n are the lengths of the target and search strings.

, . . , ( ). , . Boyer-Moore, KMP . . . , .

+1

, , :

  • . The Ruby ,

  • , , ( ), ( ).

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

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).

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
0
source

Source: https://habr.com/ru/post/1770264/


All Articles