LoginSignup
0
1

More than 5 years have passed since last update.

2つの配列を比較して、重複している値を取り出す(回答)

Last updated at Posted at 2017-02-18

It is answer1

ruby
arr1 = [2, 4, 5, 6, 7]
arr2 = [7, 8, 9, 7, 4, 3, 2]

def extract_value(arr1, arr2)
  arr3 = arr1.uniq + arr2.uniq
  arr4 = arr3.inject(Hash.new(0)){| init, v | init[v]+=1; init;}
  answer = arr4.map{|k, v|  k if v >= 2}.compact
end

extract_value(arr1, arr2)

It is answer2

ruby
arr1 = [2, 4, 5, 6, 7]
arr2 = [7, 8, 9, 7, 4, 3, 2]

require 'set'
def extract_value(arr1, arr2)
  set_val, set_val2 = Set.new, Set.new
  arr1.map{|v| set_val << v}
  arr2.each {|v| set_val2 << v if set_val.include?(v) }
  set_val2.to_a
end

extract_value(arr1, arr2)

It is answer3

ruby
arr1 & arr2

Which is a better algorithm?

Let me check

ruby
arr1, arr2 = [], []
1.upto(100000000).each {|v| arr1 << rand(1..500)}
1.upto(100000000).each {|v| arr2 << rand(1..1000)}

embed time

ruby
def extract_value1(arr1, arr2)
  puts Time.now
  arr3 = arr1.uniq + arr2.uniq
  arr4 = arr3.inject(Hash.new(0)){| init, v | init[v]+=1; init;}
  answer = arr4.map{|k, v|  k if v >= 2}.compact
  puts Time.now
  answer
end

It takes 8 seconds

text
2017-02-18 15:55:40 +0900
2017-02-18 15:55:48 +0900

embed time

ruby
require 'set'
def extract_value2(arr1, arr2)
  puts Time.now
  set_val, set_val2 = Set.new, Set.new
  arr1.map{|v| set_val << v}
  arr2.each {|v| set_val2 << v if set_val.include?(v) }
  puts Time.now
  set_val2.to_a
end

It takes 44 seconds

text
2017-02-18 15:54:49 +0900
2017-02-18 15:55:33 +0900

It looks that first algorithm is better.
I think it is because of uniq function.

I will change value of arr and function also

ruby
arr1, arr2 = [], []
1.upto(100000000).each {|v| arr1 << rand(1..5000000)}
1.upto(100000000).each {|v| arr2 << rand(1..10000000)}

I will use uniq function in second one and name extract_value3

ruby
require 'set'
def extract_value3(arr1, arr2)
  puts Time.now
  set_val, set_val2 = Set.new, Set.new
  arr1 = arr1.uniq
  arr2 = arr2.uniq
  arr1.map{|v| set_val << v}
  arr2.each {|v| set_val2 << v if set_val.include?(v) }
  puts Time.now
  set_val2.to_a
end

This is the result of extract_value1

2017-02-18 16:26:37 +0900
2017-02-18 16:29:22 +0900

This is the result of extract_value2

2017-02-18 16:45:04 +0900
2017-02-18 16:48:12 +0900

This is the result of extract_value3

2017-02-18 16:39:18 +0900
2017-02-18 16:41:20 +0900

Conclusion

3 is a best algorithm.

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1