2009-02-21 46 views
5

Tôi muốn lưu trữ chuỗi và phát hành từng chuỗi bằng một số ID duy nhất (chỉ mục sẽ là tốt). Tôi chỉ cần một bản sao của mỗi chuỗi và tôi yêu cầu tra cứu nhanh. Tôi kiểm tra xem chuỗi tồn tại trong bảng thường đủ để tôi nhận thấy hiệu suất đạt được hay không. Whats container tốt nhất để sử dụng cho việc này và làm thế nào để tôi tra cứu nếu chuỗi tồn tại?vùng chứa để tra cứu tên nhanh

Trả lời

9

Tôi sẽ đề xuất tr1 :: unordered_map. Nó được thực hiện như một hashmap vì vậy nó có độ phức tạp mong đợi của O (1) cho tra cứu và một trường hợp xấu nhất của O (n). Ngoài ra còn có một triển khai tăng cường nếu trình biên dịch của bạn không hỗ trợ tr1.

#include <string> 
#include <iostream> 
#include <tr1/unordered_map> 

using namespace std; 

int main() 
{ 
    tr1::unordered_map<string, int> table; 

    table["One"] = 1; 
    table["Two"] = 2; 

    cout << "find(\"One\") == " << boolalpha << (table.find("One") != table.end()) << endl; 
    cout << "find(\"Three\") == " << boolalpha << (table.find("Three") != table.end()) << endl; 

    return 0; 
} 
+0

Không sử dụng unordered_map trong T1, nó không có phương pháp dự trữ và nếu bạn chèn nhiều chuỗi trong giai đoạn chèn, bạn sẽ có nhiều lần khôi phục. –

+0

Cũng unordered_map cho chuỗi dài là tồi tệ hơn một std :: bản đồ –

2

Âm thanh như một mảng sẽ hoạt động tốt khi chỉ mục là chỉ mục vào mảng. Để kiểm tra xem nó có tồn tại không, chỉ cần chắc chắn rằng chỉ mục nằm trong giới hạn của mảng và rằng mục nhập của nó không phải là NULL.

EDIT: nếu bạn sắp xếp danh sách, bạn luôn có thể sử dụng tìm kiếm nhị phân cần có tra cứu nhanh.

EDIT: Ngoài ra, nếu bạn muốn tìm kiếm chuỗi, bạn luôn có thể sử dụng std::map<std::string, int>. Điều này cần phải có một số tốc độ tra cứu phong nha.

+0

Tôi có một vấn đề hiệu suất với mảng, tôi cần logN –

+0

chờ đợi để bạn muốn có thể nói tồn tại ("my_string")? –

+0

Tôi nghĩ rằng bạn muốn có thể làm: C [index] để lấy chuỗi. –

5

Thử std :: map.

2

Các chuỗi có được tìm kiếm có sẵn tĩnh không? Bạn có thể muốn xem một số perfect hashing function

1

Dễ nhất là sử dụng std :: map.

Nó hoạt động như thế này:

#include <map> 
using namespace std; 

... 

    map<string, int> myContainer; 
    myContainer["foo"] = 5; // map string "foo" to id 5 
    // Now check if "foo" has been added to the container: 
    if (myContainer.find("foo") != myContainer.end()) 
    { 
     // Yes! 
     cout << "The ID of foo is " << myContainer["foo"]; 
    } 
    // Let's get "foo" out of it 
    myContainer.erase("foo") 
+0

Như tôi đã nhận xét về câu trả lời của @ Teran: Nó sẽ không là ? Anh ta muốn tra cứu UID chứ không phải chuỗi. – strager

+0

ông nói rằng ông muốn tra cứu bằng một chuỗi trong bình luận để terans trả lời nếu tôi có anh ta ngay –

+0

cũng ông didnt ... nhưng chúng tôi đoán ông đã làm :) –

4

Trước hết bạn phải có khả năng lượng lựa chọn của bạn. Bạn cũng đã cho chúng tôi biết rằng mẫu sử dụng chính mà bạn quan tâm là tìm kiếm tra cứu, không chèn.

Hãy N là số dây mà bạn mong đợi để được có trong bảng, và để C là số trung bình của các nhân vật trong bất kỳ chuỗi được hiện diện trong bảng cho biết (hoặc trong chuỗi được kiểm tra chống lại bàn).

  1. Trong trường hợp của một băm dựa trên cách tiếp cận, đối với mỗi tra cứu bạn phải trả các chi phí sau:

    • O(C) - tính toán hash cho chuỗi bạn đang về để tìm kiếm
    • giữa O(1 x C)O(N x C), trong đó 1..N là chi phí bạn mong đợi khi duyệt qua nhóm dựa trên khóa băm, tại đây nhân với C để kiểm tra lại các ký tự trong mỗi chuỗi so với tra cứu chủ chốt
    • tổng thời gian: giữa O(2 x C)O((N + 1) x C)
  2. Trong trường hợp của một std::map cách tiếp cận dựa trên (trong đó sử dụng cây đỏ-đen), với mỗi lookup bạn trả chi phí sau:

    • tổng thời gian: giữa O(1 x C)O(log(N) x C) - nơi O(log(N)) là chi phí cây traversal tối đa, và O(C) là thời gian mà 0 generic less<> thực hiện's cần thiết để kiểm tra lại chìa khóa tra cứu của bạn trong cây traversal

Trong trường hợp giá trị lớn cho N và trong sự vắng mặt của một hàm băm mà đảm bảo ít hơn log (N) va chạm, hoặc nếu bạn chỉ muốn chơi nó an toàn, bạn nên sử dụng phương pháp dựa trên cây (std::map). Nếu N là nhỏ, bằng mọi cách, sử dụng một cách tiếp cận băm dựa trên (. Trong khi vẫn đảm bảo rằng băm va chạm là thấp)

Trước khi thực hiện bất kỳ quyết định, tuy nhiên, bạn cũng nên kiểm tra:

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