2009-03-13 42 views
5

Tôi cần lưu trữ bảng tra cứu làm thành viên cá thể trong một trong các lớp học của tôi. Bảng sẽ được khởi tạo khi đối tượng được xây dựng. Mỗi "hàng" sẽ có 3 "cột":Cấu trúc dữ liệu tốt nhất cho bảng tra cứu trong bộ nhớ này là gì?

StringKey (e.g., "car") 
EnumKey (e.g., LookupKeys.Car) 
Value (e.g, "Ths is a car.") 

Tôi muốn chọn cấu trúc dữ liệu đó sẽ mang lại hiệu quả tốt nhất cho việc tra cứu hoặc bằng các StringKey hoặc các EnumKey.

Thật khó xử khi có 2 khóa cho cùng một giá trị từ điển. Tôi đã không bao giờ gặp phải điều này trước đây, vì vậy tôi tự hỏi những gì các tiêu chuẩn là cho loại điều.

Tôi có thể tạo cấu trúc Khóa/Giá trị/Giá trị thay vì Khóa/Khóa/Giá trị, nhưng tôi tự hỏi loại tác động hiệu suất nào sẽ có.

Tôi có nghĩ về điều này sai không?

Trả lời

4

Bạn có hai hashmaps.

  • Một từ StringKey to value.

  • Một từ EnumKey đến giá trị.

Bạn không phải sao chép tất cả trường hợp Giá trị, các đối tượng đó có thể được chia sẻ giữa hai hashmaps.

Nếu đó là rất nhiều mục, bạn có thể muốn sử dụng hai sơ đồ trang thay vì hai hashmaps. Nhưng nguyên tắc cơ bản ("Chia sẻ giá trị") áp dụng cho cả hai cấu trúc. Một bộ Giá trị có hai bản đồ.

+0

OK - trong ví dụ của tôi, "trường hợp giá trị" chỉ là chuỗi. Tôi sẽ tạo 2 từ điển (một với StringKey, một với EnumKey) có giá trị chứa cùng một biến tham chiếu chuỗi. Điều đó có đúng không? –

+0

Chính xác. Trong Python đó là tất cả để có nó. Trong Java, có một string.intern() đảm bảo rằng tất cả các chuỗi intern() 'd được giảm xuống một nhóm chuỗi chung, loại bỏ một số dư thừa có thể có. –

+0

Tôi đang sử dụng C# ... bạn có biết nếu .NET sẽ tạo một bản sao của chuỗi khi tôi thêm nó vào mỗi từ điển? –

5

Vâng ... "Sai" là một cách khắc nghiệt để đặt nó. Tôi nghĩ rằng vì từ điển phổ biến nhất là "chìa khóa đơn trị" và rất nhiều nỗ lực để cung cấp cấu trúc dữ liệu hiệu quả cho bản đồ đó, nên tốt nhất là chỉ sử dụng hai trong số đó, chia sẻ bộ nhớ cho các giá trị nếu có thể.

1

Có thực sự cần thiết để nhập vào cùng một cấu trúc với cả hai loại khóa? Có thể bạn không cần tự xây dựng lại cấu trúc dữ liệu phức tạp. Bạn có thể làm một số loại đóng gói cho bảng tra cứu để bạn thực sự có hai bảng tra cứu nếu bộ nhớ không phải là một vấn đề. Bạn có thể sử dụng cấu trúc đóng gói này để mô phỏng việc có thể rút ra giá trị từ cấu trúc "giống hệt" với một trong hai loại khóa.

HOẶC

Nếu có một số cách để ánh xạ giữa giá trị enum và phím chuỗi bạn có thể đi con đường đó với chỉ có một loại bảng tra cứu.

0

Giao diện ILookup (TKey, TElement) của LINQ có thể hữu ích. Giả sử từ điển của bạn là một cái gì đó như:

Dictionary<carKey, carValue> cars; 

Bạn có thể sử dụng:

ILookUp<carValue, carKey> lookup = cars.ToLookup(x => x.Value, x => x.Key); 

(... thực sự tôi nghĩ rằng tôi có thể có một chút hiểu sai câu hỏi - nhưng một ILookUp vẫn có thể phù hợp với những hóa đơn, nhưng bộ khóa/giá trị có thể cần phải là khóa và enum.)

0

Nếu mọi giá trị được đảm bảo có thể truy cập được bằng cả hai loại khóa, ý tưởng khác sẽ là chuyển đổi một loại khóa này sang loại khóa khác. Ví dụ:

public Value getValue(String key) 
{ 
    dictionary.get(key); // normal way 
} 

public Value getValue(Enum enumKey) 
{ 
    String realKey = toKey(enumKey); 
    getValue(realKey); // use String key 
} 

Bạn có thể có Enum của bạn thực hiện phương thức toKey() trả về khóa Chuỗi hoặc có thể có một từ điển khác ánh xạ các giá trị Enum tới đối tác Chuỗi.

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