How to define Big O by comparing two arrays in Ruby

My algorithmic skills are small. I created a method to see if two arrays contain the same elements (duplicates don't matter):

one = [1, "taco", 3, 2, :piece, 4, 5, 5, 5, 5]
two = [:piece, 2, 5, 4, 1, "taco", 3]

def same_elements?(array_one, array_two)
  return true if ( (array_one - array_two).empty? && (array_two - array_one).empty? )
  return false
end

same_elements?(one, two)

This returns true (this is true). The problem is that I'm not sure how efficient this algorithm is. My first guess is O (n ^ 2), since we have to check both ab and ba. I know that O (n ^ 2) is pretty terrible. Is there a more efficient way to do this?

+4
source share
2 answers

Short answer

O (n + m) on average

O (nm), , , (. ).

array_one , array_two, O (m + n) O (n), .

Alternative

:

one = [1, "taco", 3, 2, :piece, 4, 5, 5, 5, 5]
two = [:piece, 2, 5, 4, 1, "taco", 3]

puts Set[*one] == Set[*two] #=> true
# or
puts one.to_set == two.to_set #=> true

return true if x
return false

x

, :

def same_elements?(array_one, array_two)
  (array_one - array_two).empty? && (array_two - array_one).empty?
end

Benchmark

1E6, 0 199999 ( ), - Ruby.

- , .

N = 1_000_000

one = (1..N).map{rand < 0.5 ? rand(N/5) : Object.new}
two = one.sort_by{rand}

1 , fruity , 20% , OP.

OP .

: , @engineersmnky , , , .

, , O(nm) .

:

  • 1s 1E4
  • 8s 1E5
  • 160s 1E6

rb_ary_diff array.c, , : .

rb_ary_diff - array_two ( O (m)) array_one ( O (n)), - (O ( 1) ). O (n + m).

, .

, O (n + m).

O (mn)

O (mn) - -. , , .

10_000 KeyObjects:

class KeyObject < Object
end

1 .

10_000 KeyObjects:

class KeyObject < Object
  def hash
    1
  end
end

14 !

, Ruby , 1E-20. , O (mn), , . 2 , 1E6 .

+7

m n . rb_ary_diff (. ), for, O (m) . , , , . O (n) . , , O (mn), O (mn). , , , O (mn).

- , .. O (1), , O (n). , - O (n) , O (mn). , , .

+3
source

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


All Articles