두 배열의 내용이 동일한 지 확인합니다 (순서에 상관 없음).
Rails 1.2.3과 함께 Ruby 1.8.6을 사용하고 있으며 두 배열이 동일한 순서인지 여부에 관계없이 동일한 요소를 가지고 있는지 확인해야합니다. 배열 중 하나는 중복을 포함하지 않도록 보장됩니다 (다른 하나는 대답이 아니오 일 수 있음).
내 첫 생각은
require 'set'
a.to_set == b.to_set
하지만 더 효율적이거나 관용적 인 방법이 있는지 궁금합니다.
다음을 설정하기 위해 변환 할 필요가 없습니다.
a.sort == b.sort
두 배열 A와 B의 경우 : A와 B는 다음과 같은 경우 동일한 내용을 갖습니다. (A-B).blank? and (B-A).blank?
또는 다음을 확인할 수 있습니다. ((A-B) + (B-A)).blank?
또한 @ cort3z가 제안한 대로이 솔루션 als0은 다형성 배열 즉,
A = [1 , "string", [1,2,3]]
B = [[1,2,3] , "string", 1]
(A-B).blank? and (B-A).blank? => true
# while A.uniq.sort == B.uniq.sort will throw error `ArgumentError: comparison of Fixnum with String failed`
::::::::::: 편집하다 :::::::::::::
주석에서 제안했듯이 위의 솔루션은 중복에 대해 실패합니다. 질문자가 중복에 관심이 없기 때문에 필요하지 않은 질문에 따라 (그는 자신의 배열을 확인하기 전에 설정하도록 변환하고 중복을 마스크합니다. 그가 확인하기 전에 .uniq 연산자를 사용하고 있으며 중복을 마스킹합니다.). 그러나 여전히 중복이 관심사 인 경우 카운트 확인을 추가하면 동일하게 수정됩니다 (질문에 따라 하나의 배열 만 중복을 포함 할 수 있음). 따라서 최종 솔루션은 다음과 같습니다.A.size == B.size and ((A-B) + (B-A)).blank?
속도 비교
require 'benchmark/ips'
require 'set'
a = [1, 2, 3, 4, 5, 6]
b = [1, 2, 3, 4, 5, 6]
Benchmark.ips do |x|
x.report('sort') { a.sort == b.sort }
x.report('sort!') { a.sort! == b.sort! }
x.report('to_set') { a.to_set == b.to_set }
x.report('minus') { ((a - b) + (b - a)).empty? }
end
Warming up --------------------------------------
sort 88.338k i/100ms
sort! 118.207k i/100ms
to_set 19.339k i/100ms
minus 67.971k i/100ms
Calculating -------------------------------------
sort 1.062M (± 0.9%) i/s - 5.389M in 5.075109s
sort! 1.542M (± 1.2%) i/s - 7.802M in 5.061364s
to_set 200.302k (± 2.1%) i/s - 1.006M in 5.022793s
minus 783.106k (± 1.5%) i/s - 3.942M in 5.035311s
a
및 의 요소 b
가 Comparable
이면
a.sort == b.sort
@steenslag의 의견을 기반으로 @mori의 답변 수정
예상하면 [:a, :b] != [:a, :a, :b]
to_set
작동하지 않습니다. 대신 빈도를 사용할 수 있습니다.
class Array
def frequency
p = Hash.new(0)
each{ |v| p[v] += 1 }
p
end
end
[:a, :b].frequency == [:a, :a, :b].frequency #=> false
[:a, :b].frequency == [:b, :a].frequency #=> true
Ruby 2.6 이상
Ruby difference
는 2.6 에서 도입 되었습니다.
This gives a very fast, very readable solution here, as follows:
a = [1, 2, 3, 4, 5, 6]
b = [1, 2, 3, 4, 5, 6]
a.difference(b).any?
# => false
a.difference(b.reverse).any?
# => false
a = [1, 2, 3, 4, 5, 6]
b = [1, 2, 3]
a.difference(b).any?
# => true
Running the benchmarks:
a = Array.new(1000) { rand(100) }
b = Array.new(1000) { rand(100) }
Benchmark.ips do |x|
x.report('sort') { a.sort == b.sort }
x.report('sort!') { a.sort! == b.sort! }
x.report('to_set') { a.to_set == b.to_set }
x.report('minus') { ((a - b) + (b - a)).empty? }
x.report('difference') { a.difference(b).any? }
end
sort 13.908k (± 2.6%) i/s - 69.513k in 5.001443s
sort! 14.656k (± 3.0%) i/s - 73.736k in 5.035744s
to_set 5.125k (± 2.9%) i/s - 26.023k in 5.082083s
minus 16.398k (± 2.2%) i/s - 83.181k in 5.074938s
difference 27.839k (± 5.2%) i/s - 141.048k in 5.080706s
Hope that helps someone!
If you know the arrays are of equal length and neither array contains duplicates then this works too:
( array1 & array2 ) == array1
Explanation: the &
operator in this case returns a copy of a1 sans any items not found in a2, which is the same as the original a1 iff both arrays have the same contents with no duplicates.
Analyis: Given that the order is unchanged, I'm guessing this is implemented as a double iteration so consistently O(n*n)
, notably worse for large arrays than a1.sort == a2.sort
which should perform with worst-case O(n*logn)
.
One approach is to iterate over the array with no duplicates
# assume array a has no duplicates and you want to compare to b
!a.map { |n| b.include?(n) }.include?(false)
This returns an array of trues. If any false appears, then the outer include?
will return true. Thus you have to invert the whole thing to determine if it's a match.
combining &
and size
may be fast too.
require 'benchmark/ips'
require 'set'
Benchmark.ips do |x|
x.report('sort') { a.sort == b.sort }
x.report('sort!') { a.sort! == b.sort! }
x.report('to_set') { a.to_set == b.to_set }
x.report('minus') { ((a - b) + (b - a)).empty? }
x.report('&.size') { a.size == b.size && (a & b).size == a.size }
end
Calculating -------------------------------------
sort 896.094k (±11.4%) i/s - 4.458M in 5.056163s
sort! 1.237M (± 4.5%) i/s - 6.261M in 5.071796s
to_set 224.564k (± 6.3%) i/s - 1.132M in 5.064753s
minus 2.230M (± 7.0%) i/s - 11.171M in 5.038655s
&.size 2.829M (± 5.4%) i/s - 14.125M in 5.010414s
참고URL : https://stackoverflow.com/questions/10919783/check-if-two-arrays-have-the-same-contents-in-any-order
'developer tip' 카테고리의 다른 글
Java 기본 요소 배열이 스택 또는 힙에 저장됩니까? (0) | 2020.10.04 |
---|---|
브라우저 / HTML src =“data : image / jpeg; base64…”에서 이미지 강제 다운로드 (0) | 2020.10.04 |
C # 애플리케이션에서 JsonConvert를 가져 오는 방법은 무엇입니까? (0) | 2020.10.04 |
Mac bash의 명령 줄에서 Gradle을 실행하는 방법 (0) | 2020.10.04 |
설치된 CPAN 모듈 목록은 어떻게 얻습니까? (0) | 2020.10.04 |