2012-02-16 5 views
17

Сценарий должен проверить, присутствует ли один предопределенный IP-адрес в большом массиве IP-адресов. В настоящее время я код, который функционирует, как это (говоря, что «ИПС» мой массив IP и «ф» является предопределенной ф)Самый быстрый способ найти строку в массив строки

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

Есть ли более быстрый способ сделать то же самое?

Редактировать: Возможно, я ошибочно выразил себя. Я могу сделать array.include? но я хотел бы знать: Is array.include? метод, который даст мне самый быстрый результат?

+1

Используйте Hash или Set вместо массива – Phrogz

+0

Читать http://ruby-doc.org/core-1.9.3/Enumerable.html перед любым программирования Ruby. – tokland

+0

Вы можете использовать метод 'include?', Определенный в классе 'Array', чтобы сделать эту операцию более аккуратной, я не уверен, что она увеличит скорость поиска намного –

ответ

31

Вы можете использовать Set. Он реализован поверх Hash и будет быстрее для больших наборов данных - 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

Или в вашем случае: 's = Set.new (ips)' – Phrogz

+0

Здравствуйте, снова Alex :). Исходный код метода .include кажется почти тем же, что и мой.Или это быстрее? – Cocotton

+2

@Cocotton: [намного быстрее] (http://stackoverflow.com/questions/5551168/performance-of-arrays-and-hashes-in-ruby/5552062#5552062). Вы также можете использовать хэш с ключами ip и «true» в качестве значений. – steenslag

2

Вы пробовали Array # include? функционировать?

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

Вы можете видеть из источника он делает почти точно то же самое, за исключением изначально.

+1

Это все еще операция O (n), так как она должна искать каждый элемент в массиве (даже если он находится на C). – Phrogz

+0

Я знаю, что перечисление можно сортировать, но я не знаю, как искать такой отсортированный массив. Для выполнения задания можно сделать индексный столбец базы данных. –

+1

Даже двоичный поиск - O (log n). Хеширование элемента и поиск его в хеш-таблице - это операция с постоянным временем, которая не связана с количеством сохраненных элементов. – 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

Но разве это быстрее, чем мой метод? Потому что исходный код этого, похоже, делает практически то же самое, что и мое. – Cocotton

+0

Конечно, это быстрее .. У меня есть в моем проекте .. Кроме того, когда есть метод в рубине, зачем писать дополнительный код. –

+0

@ dku.rajkumar хотел сказать, что он должен быть быстрее, поскольку '.include?' Реализуется на уровне C в классе Array. – Ikon

3

Более быстрый способ будет:

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

Чуть быстрее, так как 'each' встречается в C вместо Ruby, но он все еще O (n) по сравнению с O (1) для хэша или набора. – Phrogz

Смежные вопросы