2012-02-16 29 views
17

La secuencia de comandos debe verificar si una IP predefinida está presente en una gran variedad de direcciones IP. Actualmente código I que funciona como esto (diciendo que "IPS" es mi variedad de IP y "IP" es la dirección IP predefinida)La forma más rápida de encontrar una Cadena en una matriz de cadena

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

¿Hay una manera más rápida de hacer la misma cosa?

Editar: Podría haberme expresado erróneamente. Puedo hacer array.include? pero lo que me gustaría saber es: ¿está array.include? el método que me dará el resultado más rápido?

+1

Utilice un hash o Set lugar de una matriz – Phrogz

+0

Leer http://ruby-doc.org/core-1.9.3/Enumerable.html antes de cualquier programación Ruby. – tokland

+0

Puede utilizar el método 'include?' Definido en la clase 'Array' para hacer que esta operación se vea más nítida, no estoy seguro si aumentará la velocidad de la búsqueda. –

Respuesta

31

Puede utilizar Set. Se implementa sobre Hash y será más rápido para grandes conjuntos de datos - 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

O en su caso: 's = Set.new (ips)' – Phrogz

+0

Hola de nuevo Alex :) .include método de código fuente parece hacer casi lo mismo que el mío.¿O es realmente más rápido? – Cocotton

+2

@Cocotton: [Mucho más rápido] (http://stackoverflow.com/questions/5551168/performance-of-arrays-and-hashes-in-ruby/5552062#5552062). También puede usar un hash con ip como claves y 'verdadero' como valores. – steenslag

2

has probado el Array # include? ¿función?

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

Se puede ver en la fuente que hace casi exactamente lo mismo, excepto de forma nativa.

+1

Esto sigue siendo una operación de tiempo O (n), ya que debe buscar a través de cada elemento en la matriz (incluso si está en C). – Phrogz

+0

Sé que se puede ordenar una enumeración, pero no sé cómo buscar dicha matriz ordenada. Uno podría hacer una columna de base de datos indexada para hacer el trabajo. –

+1

Incluso una búsqueda binaria es O (log n). Hashing un elemento y buscándolo en una tabla hash es una operación de tiempo constante que no está relacionada con la cantidad de elementos almacenados. – 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

¿Pero es esto realmente más rápido que mi método? Porque el código fuente de esto parece hacer prácticamente lo mismo que el mío. – Cocotton

+0

por supuesto es más rápido ... lo he usado en mi proyecto ... además, cuando hay un método en ruby, ¿por qué deberíamos escribir código adicional? –

+0

@ dku.rajkumar quería decir que debería ser más rápido ya que '.include?' Se implementa en el nivel C en la clase Array. – Ikon

3

Una forma más rápida sería:

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

Ligeramente más rápido, ya que el 'cada' ocurre en C en lugar de Ruby, pero sigue siendo O (n) frente a O (1) para un Hash o conjunto. – Phrogz

Cuestiones relacionadas