2016-03-26 5 views
0

Ben array ve sum_of_two var:kimin sonuncu unsur erken belirir ve toplamı Bir dizide iki tamsayılar ilk kombinasyonu buluyor verilen bir değerini maçları

array = [10, 5, 1, 9, 7, 8, 2, 4, 6, 9, 3, 2, 1, 4, 8, 7, 5] 
sum_of_two = 10 

ben iki tamsayılar kombinasyonunu bulmaya çalışıyorum array, ikisinin ikinci elemanı, toplamı sum_of_two'a eşit olan bu tür kombinasyonlarınkileri arasında en erken görülür. Örneğin, her iki [5, 5] ve [1, 9] tür kombinasyonların için aday olan, ancak (array son elemanıdır) [5, 5] ikinci 5 daha önce görünür (daha sonra array içinde 1 daha görünür) [1, 9] arasında 9. Bu yüzden [1, 9]'u iade etmek istiyorum.

I combination ve find kullanarak çalıştı:

array.combination(2).find{|x,y| x + y == sum_of_two} #=> [5, 5] 

Ancak, bu dizinin, 5 ilk tamsayı bir kombinasyonunu, ve dizi boyunca diğer tamsayı, aynı zamanda 5 döndürür.

array.combination(2).find_all{|x,y| x + y == sum_of_two} 
#=> [[5, 5], [1, 9], [1, 9], [9, 1], [7, 3], [8, 2], [8, 2], [2, 8], [4, 6], [6, 4], [9, 1], [3, 7], [2, 8]] 

Ama sonra ilk almak için emin değilim: Ben find_all yerine find kullanırsanız

, ben sum_of_two kadar ekleyin iki sayının tüm kombinasyonları olsun.

+0

ne anlamda 'için '[5, 5]' aksine [1, 9] 'birinci kombinasyon? – sawa

+0

Soldan görünecek ilk kombinasyon. Diziyi soldan sağa okuyabilseydin. Bunu açıklamanın daha iyi bir yolu var mı? Bunu açıklamanın en iyi yolu olduğunu düşündüğümden, 'görünüş sırası' (soldan) yazmayı denedim. –

+0

Soldan sağa gitmek için, önce '1' veya '9' önce '5' tuşuna basmıyor musunuz? – sawa

cevap

2

ben kullanırım (biraz daha verimli Array#include? kullanmaktan daha olacaktır) ve böyle bir şey yapmak Set: Bunu,

array = [10, 5, 1, 9, 7, 8, 2, 4, 6, 9, 3, 2, 1, 4, 8, 7, 5] 
sum_of_two = 10 

require 'set' 

array.each_with_object(Set.new) do |element, set| 
    if set.include?(sum_of_two - element) 
    break [sum_of_two - element, element] 
    else 
    set << element 
    end 
end 
#=> [1, 9] 
+0

İlginç. Ben 'set' ile karşılaşmadım, bu yüzden daha fazla bir göz atacağım.Ve ben yeterince rep :-) var bir kez cevaplar her ikisini de cevaplamak emin olacağım Çok Teşekkürler! –

1
x = array.find.with_index{|e, i| array.first(i).include?(sum_of_two - e)} 
[sum_of_two - x, x] # => [1, 9] 
1

Array#combination(n) istediğiniz sırada unsurları vermez çiftleri kendiniz inşa etmelisiniz. İkinci endeksten başlıyorsanız kolay. A, O (n), yavaş uygulama ve girişini xs diyelim:

pairs = (1...xs.size).lazy.flat_map { |j| (0...j).lazy.map { |i| [xs[i], xs[j]] } } 
first_matching_pair = pairs.detect { |i, j| i + j == 10 } 
#=> [1, 9] 
İlgili konular