2012-02-16 12 views
17

Skrypt musi sprawdzić, czy jeden predefiniowany adres IP jest obecny w dużej liczbie adresów IP. Obecnie kod, który funkcjonuje jak to (mówiąc, że „IPS” jest moją tablicą IP i „IP” jest predefiniowany ip)Najszybszy sposób znalezienia ciągu znaków w tablicy ciągów

ips.each do |existsip| 
    if ip == existsip 
    puts "ip exists" 
    return 1 
    end 
end 
puts "ip doesn't exist" 
return nil 

Czy istnieje szybszy sposób, aby zrobić to samo?

Edytuj: Mogłem się niesłusznie wyrazić. Mogę zrobić array.include? ale chciałbym wiedzieć: Czy tablica.include? metoda, która da mi najszybszy wynik?

+1

Użyj Hash lub Ustaw zamiast tablicy – Phrogz

+0

Czytaj http://ruby-doc.org/core-1.9.3/Enumerable.html przed każdym programowania Ruby. – tokland

+0

Możesz użyć metody 'include?' Zdefiniowanej w klasie 'Array', aby ta operacja wyglądała ładniej, nie jestem pewna, czy zwiększy ona prędkość wyszukiwania o wiele więcej niż możliwy –

Odpowiedz

31

Można użyć Set. Jest on implementowany na szczycie skrótu i ​​będzie szybszy w przypadku dużych zbiorów danych - O (1).

require 'set' 
s = Set.new ['1.1.1.1', '1.2.3.4'] 
# => #<Set: {"1.1.1.1", "1.2.3.4"}> 
s.include? '1.1.1.1' 
# => true 
+1

Lub w twoim przypadku: 's = Set.new (ips)' – Phrogz

+0

Witaj ponownie Alex :) .include kod źródłowy metody wydaje się robić prawie to samo co moje.Czy jest rzeczywiście szybszy? – Cocotton

+2

@Cocotton: [Znacznie szybciej] (http://stackoverflow.com/questions/5551168/performance-of-arrays-and-hates-in-ruby/5552062#5552062). Możesz także użyć skrótu z wartościami IP jako kluczami i wartością "true" jako wartości. – steenslag

2

Czy wypróbowałeś Array # include? funkcjonować?

http://ruby-doc.org/core-1.9.3/Array.html#method-i-include-3F

można zobaczyć od źródła to robi prawie dokładnie to samo, z wyjątkiem natywnie.

+1

To jest wciąż operacja czasu O (n), ponieważ musi przeszukiwać każdy element w tablicy (nawet jeśli jest w C). – Phrogz

+0

Wiem, że można wyliczyć enum, ale nie wiem, jak przeszukać taki uporządkowany układ. Można wykonać indeksowaną kolumnę bazy danych, aby wykonać zadanie. –

+1

Nawet wyszukiwanie binarne to O (log n). Przeciąganie elementu i wyszukiwanie go w tabeli mieszającej jest operacją o stałym czasie, która nie jest związana z liczbą przechowywanych elementów. – Phrogz

2
ips = ['10.10.10.10','10.10.10.11','10.10.10.12'] 

ip = '10.10.10.10' 
ips.include?(ip) => true 

ip = '10.10.10.13' 
ips.include?(ip) => false 

check Documentaion here

+0

Ale czy to faktycznie jest szybsze niż moja metoda? Ponieważ kod źródłowy tego wydaje się robić praktycznie to samo co moje. – Cocotton

+0

Oczywiście, że jest szybszy .. używam w moim projekcie .. ponadto, gdy istnieje metoda w Ruby, dlaczego powinniśmy napisać dodatkowy kod. –

+0

@ dku.rajkumar chciał powiedzieć, że powinno być szybsze, ponieważ '.include?' Jest implementowane na poziomie C na klasie Array. – Ikon

3

Szybszy sposób byłoby:

if ips.include?(ip) 
    puts "ip exists" 
    return 1 
else 
    puts "ip doesn't exist" 
    return nil 
end 
+0

Nieco szybciej, ponieważ "każdy" występuje w C zamiast w Ruby, ale nadal jest O (n) w porównaniu z O (1) w przypadku skrótu lub zestawu. – Phrogz

Powiązane problemy