2012-02-16 33 views
17

Tập lệnh phải xác minh xem một IP được xác định trước có xuất hiện trong một mảng IP lớn hay không. Hiện nay tôi đang có chức năng như thế này (nói rằng "ip" là mảng của tôi về IP và "ip" là ip được xác định trước)Cách nhanh nhất để tìm một Chuỗi thành một mảng chuỗi

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

Có cách nào nhanh hơn để làm điều tương tự?

Chỉnh sửa: Tôi có thể đã thể hiện sai chính mình. Tôi có thể làm array.include? nhưng điều tôi muốn biết là: array.include? phương pháp nào sẽ cho tôi kết quả nhanh nhất?

+1

Sử dụng một Hash hoặc Set thay vì một mảng – Phrogz

+0

đọc http://ruby-doc.org/core-1.9.3/Enumerable.html trước khi bất kỳ lập trình Ruby. – tokland

+0

Bạn có thể sử dụng phương thức 'include?' Được định nghĩa trong lớp 'Mảng' để làm cho hoạt động này trông gọn hơn, tôi không chắc liệu nó có làm tăng tốc độ tra cứu nhiều –

Trả lời

31

Bạn có thể sử dụng Set. Nó được thực hiện trên đầu trang của Hash và sẽ nhanh hơn cho các tập dữ liệu lớn - 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

Hoặc trong trường hợp của bạn: 's = Set.new (ips)' – Phrogz

+0

Xin chào một lần nữa Alex :) .include phương pháp mã nguồn dường như làm gần như cùng một điều như tôi.Hay nó thực sự nhanh hơn? – Cocotton

+2

@Cocotton: [Nhanh hơn nhiều] (http://stackoverflow.com/questions/5551168/performance-of-arrays-and-hashes-in-ruby/5552062#5552062). Bạn cũng có thể sử dụng một Hash với ip là các phím và 'true' làm giá trị. – steenslag

2

bạn đã thử mảng # bao gồm chưa? chức năng?

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

Bạn có thể nhìn thấy từ nguồn nó gần như chính xác những điều tương tự, ngoại trừ nguyên bản.

+1

Đây vẫn là một hoạt động thời gian O (n), vì nó phải tìm kiếm thông qua mọi mục trong mảng (ngay cả khi nó trong C). – Phrogz

+0

Tôi biết rằng một enum có thể được sắp xếp, nhưng tôi không biết làm thế nào để tìm kiếm một mảng được sắp xếp như vậy. Người ta có thể tạo cột cơ sở dữ liệu được lập chỉ mục để thực hiện công việc. –

+1

Ngay cả tìm kiếm nhị phân cũng là O (log n). Hashing một mục và tìm kiếm nó trong một bảng băm là một hoạt động liên tục thời gian không liên quan đến số lượng các mục được lưu trữ. – 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

Nhưng điều này thực sự nhanh hơn phương pháp của tôi? Bởi vì mã nguồn của điều này dường như thực tế giống như tôi. – Cocotton

+0

ofcourse nó là nhanh hơn .. tôi đã sử dụng trong dự án của tôi .. hơn nữa khi có một phương pháp trong ruby, tại sao chúng ta nên viết thêm mã. –

+0

@ dku.rajkumar muốn nói, cần nhanh hơn vì '.include? 'Được triển khai trên cấp độ C trên lớp Array. – Ikon

3

Một cách nhanh hơn sẽ là:

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

Hơi nhanh hơn, vì 'mỗi' xuất hiện trong C thay vì Ruby, nhưng nó vẫn là O (n) so với O (1) cho một Hash hoặc Set. – Phrogz

Các vấn đề liên quan