IT

한 배열에 다른 배열의 모든 요소가 포함되어 있는지 확인하는 방법

lottoking 2020. 5. 27. 07:52
반응형

한 배열에 다른 배열의 모든 요소가 포함되어 있는지 확인하는 방법


주어진:

a1 = [5, 1, 6, 14, 2, 8]

다음의 모든 요소가 포함되어 있는지 확인하고 싶습니다.

a2 = [2, 6, 15]

이 경우 결과는 false입니다.

그러한 배열 포함을 식별하는 내장 Ruby / Rails 메소드가 있습니까?

이를 구현하는 한 가지 방법은 다음과 같습니다.

a2.index{ |x| !a1.include?(x) }.nil?

더 좋고 더 읽기 쉬운 방법이 있습니까?


a = [5, 1, 6, 14, 2, 8]
b = [2, 6, 15]

a - b
=> [5, 1, 14, 8]

b - a
=> [15]

(b - a).empty?
=> false

아마도 이것은 더 읽기 쉽습니다.

a2.all? { |e| a1.include?(e) }

배열 교차를 사용할 수도 있습니다.

(a1 & a2).size == a1.size

참고 size단지 속도 여기에 사용됩니다, 당신은 또한 (느리게) 할 수 있습니다 :

(a1 & a2) == a1

그러나 첫 번째가 더 읽기 쉽다고 생각합니다. 이 3 개는 일반 루비입니다 (레일 아님).


이것은 수행하여 달성 할 수 있습니다

(a2 & a1) == a2

이렇게하면 두 배열의 교집합이 만들어지고에있는 모든 요소가 반환 a2됩니다 a1. 결과가와 동일 a2하면 모든 요소가에 포함되어 있는지 확인할 수 있습니다 a1.

이 방법은 모든 요소 a2가 처음에 서로 다른 경우에만 작동합니다 . 복식이 있으면이 방법은 실패합니다. Tempos의 것이 여전히 작동하므로 전적으로 그의 접근 방식을 추천합니다 (아마도 더 빠릅니다).


중복 요소가 없거나 신경 쓰지 않으면 Set 클래스를 사용할 수 있습니다 .

a1 = Set.new [5, 1, 6, 14, 2, 8]
a2 = Set.new [2, 6, 15]
a1.subset?(a2)
=> false

이 장면 뒤에서

all? { |o| set.include?(o) }

Array 클래스를 원숭이 패치 할 수 있습니다.

class Array
    def contains_all?(ary)
        ary.uniq.all? { |x| count(x) >= ary.count(x) }
    end
end

테스트

irb(main):131:0> %w[a b c c].contains_all? %w[a b c]
=> true
irb(main):132:0> %w[a b c c].contains_all? %w[a b c c]
=> true
irb(main):133:0> %w[a b c c].contains_all? %w[a b c c c]
=> false
irb(main):134:0> %w[a b c c].contains_all? %w[a]
=> true
irb(main):135:0> %w[a b c c].contains_all? %w[x]
=> false
irb(main):136:0> %w[a b c c].contains_all? %w[]
=> true
irb(main):137:0> %w[a b c d].contains_all? %w[d c h]
=> false
irb(main):138:0> %w[a b c d].contains_all? %w[d b c]
=> true

물론이 방법은 표준 단독 방법으로 작성 될 수 있습니다.

def contains_all?(a,b)
    b.uniq.all? { |x| a.count(x) >= b.count(x) }
end

그리고 당신은 그것을 호출 할 수 있습니다

contains_all?(%w[a b c c], %w[c c c])

실제로 프로파일 링 후 다음 버전이 훨씬 빠르며 코드가 더 짧습니다.

def contains_all?(a,b)
    b.all? { |x| a.count(x) >= b.count(x) }
end

배열의 크기에 따라 효율적인 알고리즘 O (n log n)을 고려할 수 있습니다.

def equal_a(a1, a2)
  a1sorted = a1.sort
  a2sorted = a2.sort
  return false if a1.length != a2.length
  0.upto(a1.length - 1) do 
    |i| return false if a1sorted[i] != a2sorted[i]
  end
end

Sorting costs O(n log n) and checking each pair costs O(n) thus this algorithm is O(n log n). The other algorithms cannot be faster (asymptotically) using unsorted arrays.


Most answers based on (a1 - a2) or (a1 & a2) would not work if there are duplicate elements in either array. I arrived here looking for a way to see if all letters of a word (split to an array) were part of a set of letters (for scrabble for example). None of these answers worked, but this one does:

def contains_all?(a1, a2)
  try = a1.chars.all? do |letter|
    a1.count(letter) <= a2.count(letter)
  end
  return try
end

참고URL : https://stackoverflow.com/questions/7387937/how-to-determine-if-one-array-contains-all-elements-of-another-array

반응형