2012-03-25 2 views
1

Was ist der beste Weg, dies in Ruby zu erreichen? Array1 enthält wenige Zahlen Array2 enthält unsortierte Zahlen. Wir möchten herausfinden, wie oft jedes Element von Array1 in Array2 angezeigt wird.Wie ermittelt man, wie oft ein Element in Array1 in Array2 vorhanden ist?

Beispiel:

Array1 = [0,1,2,3] 

Array2 = [0,0,0,3,3,3,2,1,0,3,6,1,3] 

Result = {"0"=>4, "1"=>2, "2"=>1, "3"=>5} 

Gibt es einen besseren optimalen Weg, dies zu tun, als:

  • jedes Element Array1
  • über Array2 Iterieren Kommissionierung
  • einen Zähler bei jederjedejedes Elementen Inkrementieren Übereinstimmung

Beispiel zeigt nur einige Zahlen, aber ich möchte herausfinden, wie dies am besten für einen sehr großen Array-Satz funktioniert.

+0

Es scheint mir, wie ähnlichen Algorithmus so die Effizienz der Sortierung an die Sie ist in der Reihenfolge der Sortieralgorithmen erhalten können, die vorhanden sind. http://en.wikipedia.org/wiki/Sorting_algorithm kann "nlogn" sein, wenn Sie das Mergesort-Prinzip verwenden. – uday

+0

@uDaY: Sie können das tatsächlich in 'O (n)' tun. –

Antwort

1

können Sie group_by verwenden Sie die Elemente in array2 zu zählen:

irb(main):001:0> array1 = [0,1,2,3] 
=> [0, 1, 2, 3] 
irb(main):002:0> array2 = [0,0,0,3,3,3,2,1,0,3,6,1,3] 
=> [0, 0, 0, 3, 3, 3, 2, 1, 0, 3, 6, 1, 3] 
irb(main):003:0> h = Hash[array2.group_by { |x| x }.map { |k, v| [k, v.size] }] 
=> {0=>4, 3=>5, 2=>1, 1=>2, 6=>1} 

Wenn Sie möchten, können Sie dann extrahieren Sie die Sub-Hash mit den Tasten aus array1 (aber ich glaube nicht, das wirklich notwendig ist,):

irb(main):004:0> h.select { |k,_| array1.include?(k) } 
=> {0=>4, 3=>5, 2=>1, 1=>2} 
0

Wenn die Zahlen in einem Array nicht sehr groß sind, dann können Sie ein Array mit Größe als das größte Element eines des Arrays machen. Dann wiederholen Sie das Array einmal und erhöht die Position um 1 d

Suppose the largest element in array 2 is 10 
declare an array with length 10 i.e a[10] and initialize the array with 0 
Now suppose you find 1 in array2 then increment a[1] 
If you find 4 in array2 then increment a[4] and so on 
Then again iterate over array1 once and match the corresponding element 

Ich habe nicht die Sprache als Rubin angesehen, aber wenn Sie auf die Idee gekommen sind, dann ist es ziemlich einfach, in jeder Sprache zu implementieren. Komplexität: O (n)

+0

'group_by' verwendet ein sehr ähnliches Konzept, nur speichert es die Elemente in einer Hash-Tabelle und nicht in einem Array (das Schreiben in eine Hash-Tabelle ist jedoch auch' O (1) '). –

+0

Wie in vielen anderen interpretierten Programmiersprachen behandelt Ruby Arrays nicht als Instanzen mit einer unveränderlichen Größe, sondern eher als eine Zusammenführung zwischen klassischen Arrays und Listen. – robustus

+0

@robustus: Sie müssten die Elemente hier noch initialisieren, also kann "ein Array der Länge 10 deklarieren" als etwas wie "a = [0] * 10" interpretiert werden, was sinnvoll erscheint und zu klassischen Vektordaten führt Struktur mit 'O (1)' Zugang zu seinen Mitgliedern. –

0
a = [0,1,2,3] 
b = [0,0,0,3,3,3,2,1,0,3,6,1,3] 

a.inject({}){|h,i| h[i] = b.count(i); h} 
#=> {0=>4, 1=>2, 2=>1, 3=>5} 

oder

Hash[a.map{|i| [i,b.count(i)]}] 
#=> {0=>4, 1=>2, 2=>1, 3=>5} 
+0

OP wollte die separaten Durchgänge durch das zweite Array vermeiden. –

Verwandte Themen