2008-12-15 16 views
6

Tôi có cấu trúc nútChức năng nào trong thư viện std là ở đó để tìm kiếm nhị phân một vector và tìm một phần tử?

struct Node{CString text, int id;}; 

trong một véc tơ được sắp xếp.

Tôi tự hỏi nếu có một hàm trong thuật toán sẽ thực hiện tìm kiếm nhị phân vectơ và tìm phần tử.

+1

Bạn có chắc chắn về dấu phẩy giữa CString không? Đó không phải là dấu chấm phẩy sao? – razeh

Trả lời

20

std::binary_search() sẽ cho bạn biết nếu một giá trị tồn tại trong thùng sơn.

std::lower_bound()/std::upper_bound() sẽ trả về một trình lặp cho lần xuất hiện đầu tiên/cuối cùng của giá trị

Đối tượng của bạn cần triển khai operator< để các thuật toán này hoạt động.

+4

hoặc bạn cần sử dụng quá tải khác cho 'binary_search' và cung cấp một bộ so sánh ở tham số thứ 4. Điều này cần phải là cùng một bộ so sánh bạn đã sử dụng để sắp xếp. – KitsuneYMG

+0

"Không giống như lower_bound, cho upper_bound giá trị được chỉ bởi iterator được trả về bởi hàm này không được ** tương đương ** với val, chỉ lớn hơn. –

6

Vâng, có một chức năng gọi là "binary_search" std :: binary_search

Bạn cho nó đầu tiên, cuối cùng và một giá trị hoặc một vị.

Xem here cho một mẫu

Kết hợp với Martin York's toán tử == và bạn sẽ có OK (hoặc bạn có thể viết một functor vị

+0

Trên thực tế tìm kiếm nhị phân, bạn cần toán tử <, không phải toán tử == –

+0

boost :: bind (& Node :: text, _1)

+1

Cũng lưu ý rằng nó không tìm thấy phần tử. Nó chỉ kiểm tra sự tồn tại. –

0

Thay vì vector được sắp xếp < Nút >
Tại sao không sử dụng bản đồ. Đây là một container được sắp xếp. Vì vậy, bất kỳ tìm kiếm được thực hiện trên điều này thông qua std :: find() tự động có các thuộc tính giống như một tìm kiếm nhị phân.

+0

Nếu dữ liệu của bạn ổn định (không có bổ sung/xóa liên tục), thì bộ nhớ sẽ hiệu quả hơn khi sử dụng vectơ. Nếu bạn cần tương tác với các phần khác của hệ thống mong đợi Hoặc bạn cần phải truy cập dữ liệu theo chỉ mục hoặc dữ liệu được truy cập trong một vòng lặp chặt chẽ, nơi mà bộ nhớ địa phương là quan trọng – KeithB

+0

"Một vector được sắp xếp cho phép bạn lặp qua các nội dung theo thứ tự." cho (std :: map :: iterator i = map.begin(); i! = map.end(); ++ i) ...) –

+1

một bản đồ cũng không thỏa thuận thuận lợi với nhiều phiên bản của – baash05

0

Sử dụng std::equal_range để tìm một loạt các phần tử trong một véc tơ được sắp xếp. std::equal_range trả về số std::pair của vòng lặp, cho bạn phạm vi trong vectơ của các phần tử bằng đối số bạn cung cấp. Nếu phạm vi trống, thì mục của bạn không có trong vectơ và độ dài của phạm vi cho bạn biết số lần mục của bạn xuất hiện trong vectơ.

Dưới đây là một ví dụ sử dụng ints thay vì struct Node:

#include <iostream> 
#include <algorithm> 
#include <vector> 
#include <string> 

int main(int argc, const char * argv[]) 
{ 
    std::vector<int> sorted = { 1, 2, 2, 5, 10 }; 

    auto range = std::equal_range(sorted.begin(), sorted.end(), 20); 
    // Outputs "5 5" 
    std::cout << std::distance(sorted.begin(), range.first) << ' ' 
       << std::distance(sorted.begin(), range.second) << '\n'; 

    range = std::equal_range(sorted.begin(), sorted.end(), 5); 
    // Outputs "3 4" 
    std::cout << std::distance(sorted.begin(), range.first) << ' ' 
       << std::distance(sorted.begin(), range.second) << '\n'; 

    range = std::equal_range(sorted.begin(), sorted.end(), -1); 
    // Outputs "0 0" 
    std::cout << std::distance(sorted.begin(), range.first) << ' ' 
       << std::distance(sorted.begin(), range.second) << '\n'; 

    return 0; 
} 

Để làm công việc này với struct Node bạn hoặc sẽ phải cung cấp một operator < cho struct Node hoặc vượt qua trong một so sánh để std::equal_range. Bạn có thể làm điều đó bằng cách cung cấp lambda làm đối số cho std::equal_range để so sánh cấu trúc của bạn.

std::vector<Node> nodes = { Node{"hello", 5}, Node{"goodbye", 6} }; 
Node searchForMe { "goodbye", 6 }; 
auto range = std::equal_range(nodes.begin(), nodes.end(), searchForMe, 
           [](Node lhs, Node rhs) { return lhs.id < rhs.id; });