Khóa trùng lặp trong từ điển .NET?


256

Có bất kỳ lớp từ điển nào trong thư viện lớp cơ sở .NET cho phép sử dụng các khóa trùng lặp không? Giải pháp duy nhất tôi tìm thấy là tạo ra, ví dụ, một lớp như:

Dictionary<string, List<object>>

Nhưng điều này là khá khó chịu để thực sự sử dụng. Trong Java, tôi tin rằng MultiMap thực hiện điều này, nhưng không thể tìm thấy một tương tự trong .NET.


3
Khóa trùng lặp này là giá trị trùng lặp (Danh sách) như thế nào?
Shamim Hafiz

1
@ShamimHafiz, không, các giá trị không cần phải trùng lặp. Nếu bạn phải lưu trữ các bản sao { a, 1 }{ a, 2 }trong bảng băm nơi alà khóa, một thay thế là phải có { a, [1, 2] }.
nawfal

1
Trên thực tế, tôi tin rằng những gì thực sự muốn ở đây là một bộ sưu tập trong đó mỗi khóa có thể ánh xạ tới một hoặc nhiều giá trị. Tôi nghĩ rằng biểu thức "khóa trùng lặp" không thực sự truyền đạt điều này.
DavidRR

Để tham khảo trong tương lai, bạn nên xem xét giữ 1 khóa chỉ thêm các giá trị vào nó thay vì lặp đi lặp lại các khóa tương tự.
Ya Wang

Nếu cả khóa và giá trị là chuỗi thì có NameValueCollection (có thể liên kết nhiều giá trị chuỗi với mỗi khóa chuỗi).
AnorZaken

Câu trả lời:


229

Nếu bạn đang sử dụng .NET 3.5, hãy sử dụng Lookuplớp.

EDIT: Bạn thường tạo ra Lookupbằng cách sử dụng Enumerable.ToLookup. Điều này không cho rằng bạn không cần thay đổi nó sau đó - nhưng tôi thường thấy điều đó đủ tốt.

Nếu điều đó không phù hợp với bạn, tôi không nghĩ có gì trong khung sẽ giúp ích - và sử dụng từ điển cũng tốt như vậy :(


Cảm ơn bạn đã tìm kiếm trên Tra cứu. Nó cung cấp một cách tuyệt vời để phân vùng (nhóm) kết quả từ truy vấn linq không phải là tiêu chí đặt hàng tiêu chuẩn.
Robert Paulson

3
@Josh: Bạn sử dụng Enumerable.ToLookup để tạo một cái.
Jon Skeet

29
Lời cảnh báo : Lookupkhông được tuần tự hóa
SliverNinja - MSFT

1
Làm thế nào chúng ta nên thêm các mục vào Tra cứu đó?
moldovanu

171

Lớp List thực sự hoạt động khá tốt đối với các bộ sưu tập khóa / giá trị có chứa các bản sao mà bạn muốn lặp lại trên bộ sưu tập. Thí dụ:

List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();

// add some values to the collection here

for (int i = 0;  i < list.Count;  i++)
{
    Print(list[i].Key, list[i].Value);
}

31
Giải pháp này hoạt động theo chức năng, nhưng việc triển khai Danh sách không có kiến ​​thức về khóa hoặc giá trị và không thể tối ưu hóa việc tìm kiếm khóa
Spencer Rose

41

Đây là một cách để làm điều này với Danh sách <KeyValuePair <chuỗi, chuỗi >>

public class ListWithDuplicates : List<KeyValuePair<string, string>>
{
    public void Add(string key, string value)
    {
        var element = new KeyValuePair<string, string>(key, value);
        this.Add(element);
    }
}

var list = new ListWithDuplicates();
list.Add("k1", "v1");
list.Add("k1", "v2");
list.Add("k1", "v3");

foreach(var item in list)
{
    string x = string.format("{0}={1}, ", item.Key, item.Value);
}

Đầu ra k1 = v1, k1 = v2, k1 = v3


Hoạt động tuyệt vời trong kịch bản của tôi và cũng dễ sử dụng.
dùng6121177

21

Nếu bạn đang sử dụng các chuỗi làm cả khóa và giá trị, bạn có thể sử dụng System.Collections.ecialized.NameValueCollection , sẽ trả về một mảng các giá trị chuỗi thông qua phương thức GetValues ​​(khóa chuỗi).


6
NameValueCollection không cho phép nhiều khóa.
Jenny O'Reilly

@Jenny O'Reilly: Chắc chắn, bạn có thể thêm các khóa trùng lặp.
isHuman

Nói đúng ra @ JennyO'Reilly là chính xác, vì các nhận xét trên trang MSDN được liên kết nêu rõ: lớp này lưu trữ nhiều giá trị chuỗi dưới một khóa .
Ronald

Nó sẽ cho phép nhưng sẽ trả về nhiều giá trị, tôi đã thử sử dụng chỉ mục và khóa.
dùng6121177

18

Tôi vừa đi qua thư viện PowerCollections , trong đó có một lớp gọi là MultiDipedia. Điều này gọn gàng kết thúc loại chức năng này.


14

Lưu ý rất quan trọng liên quan đến việc sử dụng Tra cứu:

Bạn có thể tạo một thể hiện của một Lookup(TKey, TElement)bằng cách gọi ToLookupmột đối tượng thực hiệnIEnumerable(T)

Không có nhà xây dựng nào để tạo một thể hiện mới của a Lookup(TKey, TElement). Ngoài ra, Lookup(TKey, TElement)các đối tượng là bất biến, nghĩa là, bạn không thể thêm hoặc xóa các thành phần hoặc khóa khỏi một Lookup(TKey, TElement)đối tượng sau khi nó được tạo.

(từ MSDN)

Tôi nghĩ rằng đây sẽ là một điểm dừng chương trình cho hầu hết các mục đích sử dụng.


6
Tôi có thể nghĩ về rất ít sử dụng trong đó đây sẽ là một điểm dừng chương trình. Nhưng sau đó, tôi nghĩ những vật bất biến là tuyệt vời.
Joel Mueller

1
@JoelMueller Tôi có thể nghĩ ra rất nhiều trường hợp đây là một điểm dừng chương trình. Phải tạo lại một từ điển để thêm một mục không phải là một giải pháp đặc biệt hiệu quả ...
thiệu lại

12

Tôi nghĩ rằng một cái gì đó như List<KeyValuePair<object, object>>sẽ làm công việc.


Làm thế nào để bạn tìm kiếm một cái gì đó trong danh sách đó bằng chìa khóa của nó?
Wayne Bloss

Bạn phải lặp lại qua nó: nhưng tôi không biết về LookUp-Class của .NET 3.5: có lẽ điều này hữu ích hơn cho việc tìm kiếm trong nội dung của nó.
MADMap

2
@wizlib: Cách duy nhất là lặp qua danh sách, điều này gần như không hiệu quả như băm. -1
petr k.

@petrk. Điều đó thực sự phụ thuộc vào dữ liệu của bạn là gì. Tôi đã sử dụng triển khai này vì tôi có rất ít khóa duy nhất và không muốn chịu chi phí va chạm băm. +1
Evan M

9

Nếu bạn đang sử dụng> = .NET 4 thì bạn có thể sử dụng TupleClass:

// declaration
var list = new List<Tuple<string, List<object>>>();

// to add an item to the list
var item = Tuple<string, List<object>>("key", new List<object>);
list.Add(item);

// to iterate
foreach(var i in list)
{
    Console.WriteLine(i.Item1.ToString());
}

Điều này trông giống như một List<KeyValuePair<key, value>>giải pháp như trên. Liệu tôi có sai?
Nathan Goings

6

Thật dễ dàng để "cuộn" phiên bản từ điển của riêng bạn cho phép các mục nhập "khóa trùng lặp". Đây là một thực hiện đơn giản thô. Bạn có thể muốn xem xét thêm hỗ trợ cho hầu hết (nếu không phải tất cả) trên IDictionary<T>.

public class MultiMap<TKey,TValue>
{
    private readonly Dictionary<TKey,IList<TValue>> storage;

    public MultiMap()
    {
        storage = new Dictionary<TKey,IList<TValue>>();
    }

    public void Add(TKey key, TValue value)
    {
        if (!storage.ContainsKey(key)) storage.Add(key, new List<TValue>());
        storage[key].Add(value);
    }

    public IEnumerable<TKey> Keys
    {
        get { return storage.Keys; }
    }

    public bool ContainsKey(TKey key)
    {
        return storage.ContainsKey(key);
    }

    public IList<TValue> this[TKey key]
    {
        get
        {
            if (!storage.ContainsKey(key))
                throw new KeyNotFoundException(
                    string.Format(
                        "The given key {0} was not found in the collection.", key));
            return storage[key];
        }
    }
}

Một ví dụ nhanh về cách sử dụng nó:

const string key = "supported_encodings";
var map = new MultiMap<string,Encoding>();
map.Add(key, Encoding.ASCII);
map.Add(key, Encoding.UTF8);
map.Add(key, Encoding.Unicode);

foreach (var existingKey in map.Keys)
{
    var values = map[existingKey];
    Console.WriteLine(string.Join(",", values));
}

4

Trả lời cho câu hỏi ban đầu. Một cái gì đó giống như Dictionary<string, List<object>>được thực hiện trong một lớp được gọi là MultiMaptrongCode Project .

Bạn có thể tìm thêm thông tin vào liên kết dưới đây: http://www.codeproject.com/KB/cs/MultiKeyDipedia.aspx


3

NameValueCollection hỗ trợ nhiều giá trị chuỗi dưới một khóa (cũng là một chuỗi), nhưng đó là ví dụ duy nhất tôi biết.

Tôi có xu hướng tạo các cấu trúc tương tự như trong ví dụ của bạn khi tôi gặp phải tình huống tôi cần loại chức năng đó.


3

Khi sử dụng List<KeyValuePair<string, object>>tùy chọn, bạn có thể sử dụng LINQ để thực hiện tìm kiếm:

List<KeyValuePair<string, object>> myList = new List<KeyValuePair<string, object>>();
//fill it here
var q = from a in myList Where a.Key.Equals("somevalue") Select a.Value
if(q.Count() > 0){ //you've got your value }

2
Có, nhưng điều đó không làm cho nó nhanh hơn (vẫn không bị băm)
Haukman

3

Vì C # mới (tôi tin là từ 7.0), bạn cũng có thể làm một cái gì đó như thế này:

var duplicatedDictionaryExample = new List<(string Key, string Value)> { ("", "") ... }

và bạn đang sử dụng nó làm Danh sách tiêu chuẩn, nhưng với hai giá trị được đặt tên theo bất cứ điều gì bạn muốn

foreach(var entry in duplicatedDictionaryExample)
{ 
    // do something with the values
    entry.Key;
    entry.Value;
}

2

Bạn có nghĩa là đồng dạng và không phải là một bản sao thực tế? Nếu không, một hashtable sẽ không thể làm việc.

Đồng dạng có nghĩa là hai khóa riêng biệt có thể băm với giá trị tương đương, nhưng các khóa không bằng nhau.

Ví dụ: giả sử hàm băm của hashtable của bạn chỉ là hashval = key mod 3. Cả 1 và 4 ánh xạ thành 1, nhưng là các giá trị khác nhau. Đây là nơi mà ý tưởng của bạn về một danh sách phát huy tác dụng.

Khi bạn cần tra cứu 1, giá trị đó được băm thành 1, danh sách được duyệt qua cho đến khi tìm thấy Khóa = 1.

Nếu bạn cho phép chèn các khóa trùng lặp, bạn sẽ không thể phân biệt khóa nào ánh xạ tới giá trị nào.


2
Một bảng băm đã xử lý các khóa xảy ra để băm đến cùng một giá trị (điều này được gọi là xung đột). Tôi đang đề cập đến một tình huống mà bạn muốn ánh xạ nhiều giá trị vào cùng một khóa chính xác.

2

Cách tôi sử dụng chỉ là một

Dictionary<string, List<string>>

Bằng cách này, bạn có một phím duy nhất chứa một danh sách các chuỗi.

Thí dụ:

List<string> value = new List<string>();
if (dictionary.Contains(key)) {
     value = dictionary[key];
}
value.Add(newValue);

Thật đẹp và sạch sẽ.
Jerry Nixon

Đây là một giải pháp tuyệt vời để xử lý trường hợp sử dụng của tôi.
dub stylee

1

Tôi tình cờ tìm thấy bài đăng này để tìm kiếm cùng một câu trả lời, và không tìm thấy, vì vậy tôi đã tìm ra một giải pháp ví dụ đơn giản bằng cách sử dụng danh sách từ điển, ghi đè toán tử [] để thêm từ điển mới vào danh sách khi tất cả những người khác có khóa đã cho (bộ) và trả về danh sách các giá trị (get).
Nó xấu và không hiệu quả, nó CHỈ lấy / đặt theo khóa và nó luôn trả về một danh sách, nhưng nó hoạt động:

 class DKD {
        List<Dictionary<string, string>> dictionaries;
        public DKD(){
            dictionaries = new List<Dictionary<string, string>>();}
        public object this[string key]{
             get{
                string temp;
                List<string> valueList = new List<string>();
                for (int i = 0; i < dictionaries.Count; i++){
                    dictionaries[i].TryGetValue(key, out temp);
                    if (temp == key){
                        valueList.Add(temp);}}
                return valueList;}
            set{
                for (int i = 0; i < dictionaries.Count; i++){
                    if (dictionaries[i].ContainsKey(key)){
                        continue;}
                    else{
                        dictionaries[i].Add(key,(string) value);
                        return;}}
                dictionaries.Add(new Dictionary<string, string>());
                dictionaries.Last()[key] =(string)value;
            }
        }
    }

1

Tôi đã thay đổi câu trả lời của @Hector Correa thành một phần mở rộng với các loại chung chung và cũng đã thêm một TryGetValue tùy chỉnh cho nó.

  public static class ListWithDuplicateExtensions
  {
    public static void Add<TKey, TValue>(this List<KeyValuePair<TKey, TValue>> collection, TKey key, TValue value)
    {
      var element = new KeyValuePair<TKey, TValue>(key, value);
      collection.Add(element);
    }

    public static int TryGetValue<TKey, TValue>(this List<KeyValuePair<TKey, TValue>> collection, TKey key, out IEnumerable<TValue> values)
    {
      values = collection.Where(pair => pair.Key.Equals(key)).Select(pair => pair.Value);
      return values.Count();
    }
  }

0

Đây là một cách kéo theo từ điển đồng thời Tôi nghĩ rằng điều này sẽ giúp bạn:

public class HashMapDictionary<T1, T2> : System.Collections.IEnumerable
{
    private System.Collections.Concurrent.ConcurrentDictionary<T1, List<T2>> _keyValue = new System.Collections.Concurrent.ConcurrentDictionary<T1, List<T2>>();
    private System.Collections.Concurrent.ConcurrentDictionary<T2, List<T1>> _valueKey = new System.Collections.Concurrent.ConcurrentDictionary<T2, List<T1>>();

    public ICollection<T1> Keys
    {
        get
        {
            return _keyValue.Keys;
        }
    }

    public ICollection<T2> Values
    {
        get
        {
            return _valueKey.Keys;
        }
    }

    public int Count
    {
        get
        {
            return _keyValue.Count;
        }
    }

    public bool IsReadOnly
    {
        get
        {
            return false;
        }
    }

    public List<T2> this[T1 index]
    {
        get { return _keyValue[index]; }
        set { _keyValue[index] = value; }
    }

    public List<T1> this[T2 index]
    {
        get { return _valueKey[index]; }
        set { _valueKey[index] = value; }
    }

    public void Add(T1 key, T2 value)
    {
        lock (this)
        {
            if (!_keyValue.TryGetValue(key, out List<T2> result))
                _keyValue.TryAdd(key, new List<T2>() { value });
            else if (!result.Contains(value))
                result.Add(value);

            if (!_valueKey.TryGetValue(value, out List<T1> result2))
                _valueKey.TryAdd(value, new List<T1>() { key });
            else if (!result2.Contains(key))
                result2.Add(key);
        }
    }

    public bool TryGetValues(T1 key, out List<T2> value)
    {
        return _keyValue.TryGetValue(key, out value);
    }

    public bool TryGetKeys(T2 value, out List<T1> key)
    {
        return _valueKey.TryGetValue(value, out key);
    }

    public bool ContainsKey(T1 key)
    {
        return _keyValue.ContainsKey(key);
    }

    public bool ContainsValue(T2 value)
    {
        return _valueKey.ContainsKey(value);
    }

    public void Remove(T1 key)
    {
        lock (this)
        {
            if (_keyValue.TryRemove(key, out List<T2> values))
            {
                foreach (var item in values)
                {
                    var remove2 = _valueKey.TryRemove(item, out List<T1> keys);
                }
            }
        }
    }

    public void Remove(T2 value)
    {
        lock (this)
        {
            if (_valueKey.TryRemove(value, out List<T1> keys))
            {
                foreach (var item in keys)
                {
                    var remove2 = _keyValue.TryRemove(item, out List<T2> values);
                }
            }
        }
    }

    public void Clear()
    {
        _keyValue.Clear();
        _valueKey.Clear();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return _keyValue.GetEnumerator();
    }
}

ví dụ:

public class TestA
{
    public int MyProperty { get; set; }
}

public class TestB
{
    public int MyProperty { get; set; }
}

            HashMapDictionary<TestA, TestB> hashMapDictionary = new HashMapDictionary<TestA, TestB>();

            var a = new TestA() { MyProperty = 9999 };
            var b = new TestB() { MyProperty = 60 };
            var b2 = new TestB() { MyProperty = 5 };
            hashMapDictionary.Add(a, b);
            hashMapDictionary.Add(a, b2);
            hashMapDictionary.TryGetValues(a, out List<TestB> result);
            foreach (var item in result)
            {
                //do something
            }

0

tôi sử dụng lớp đơn giản này:

public class ListMap<T,V> : List<KeyValuePair<T, V>>
{
    public void Add(T key, V value) {
        Add(new KeyValuePair<T, V>(key, value));
    }

    public List<V> Get(T key) {
        return FindAll(p => p.Key.Equals(key)).ConvertAll(p=> p.Value);
    }
}

sử dụng:

var fruits = new ListMap<int, string>();
fruits.Add(1, "apple");
fruits.Add(1, "orange");
var c = fruits.Get(1).Count; //c = 2;

0

Bạn có thể tạo trình bao bọc từ điển của riêng mình, một cái gì đó giống như cái này, như một phần thưởng, nó hỗ trợ giá trị null dưới dạng khóa:

/// <summary>
/// Dictionary which supports duplicates and null entries
/// </summary>
/// <typeparam name="TKey">Type of key</typeparam>
/// <typeparam name="TValue">Type of items</typeparam>
public class OpenDictionary<TKey, TValue>
{
    private readonly Lazy<List<TValue>> _nullStorage = new Lazy<List<TValue>>(
        () => new List<TValue>());

    private readonly Dictionary<TKey, List<TValue>> _innerDictionary =
        new Dictionary<TKey, List<TValue>>();

    /// <summary>
    /// Get all entries
    /// </summary>
    public IEnumerable<TValue> Values =>
        _innerDictionary.Values
            .SelectMany(x => x)
            .Concat(_nullStorage.Value);

    /// <summary>
    /// Add an item
    /// </summary>
    public OpenDictionary<TKey, TValue> Add(TKey key, TValue item)
    {
        if (ReferenceEquals(key, null))
            _nullStorage.Value.Add(item);
        else
        {
            if (!_innerDictionary.ContainsKey(key))
                _innerDictionary.Add(key, new List<TValue>());

            _innerDictionary[key].Add(item);
        }

        return this;
    }

    /// <summary>
    /// Remove an entry by key
    /// </summary>
    public OpenDictionary<TKey, TValue> RemoveEntryByKey(TKey key, TValue entry)
    {
        if (ReferenceEquals(key, null))
        {
            int targetIdx = _nullStorage.Value.FindIndex(x => x.Equals(entry));
            if (targetIdx < 0)
                return this;

            _nullStorage.Value.RemoveAt(targetIdx);
        }
        else
        {
            if (!_innerDictionary.ContainsKey(key))
                return this;

            List<TValue> targetChain = _innerDictionary[key];
            if (targetChain.Count == 0)
                return this;

            int targetIdx = targetChain.FindIndex(x => x.Equals(entry));
            if (targetIdx < 0)
                return this;

            targetChain.RemoveAt(targetIdx);
        }

        return this;
    }

    /// <summary>
    /// Remove all entries by key
    /// </summary>
    public OpenDictionary<TKey, TValue> RemoveAllEntriesByKey(TKey key)
    {
        if (ReferenceEquals(key, null))
        {
            if (_nullStorage.IsValueCreated)
                _nullStorage.Value.Clear();
        }       
        else
        {
            if (_innerDictionary.ContainsKey(key))
                _innerDictionary[key].Clear();
        }

        return this;
    }

    /// <summary>
    /// Try get entries by key
    /// </summary>
    public bool TryGetEntries(TKey key, out IReadOnlyList<TValue> entries)
    {
        entries = null;

        if (ReferenceEquals(key, null))
        {
            if (_nullStorage.IsValueCreated)
            {
                entries = _nullStorage.Value;
                return true;
            }
            else return false;
        }
        else
        {
            if (_innerDictionary.ContainsKey(key))
            {
                entries = _innerDictionary[key];
                return true;
            }
            else return false;
        }
    }
}

Mẫu sử dụng:

var dictionary = new OpenDictionary<string, int>();
dictionary.Add("1", 1); 
// The next line won't throw an exception; 
dictionary.Add("1", 2);

dictionary.TryGetEntries("1", out List<int> result); 
// result is { 1, 2 }

dictionary.Add(null, 42);
dictionary.Add(null, 24);
dictionary.TryGetEntries(null, out List<int> result); 
// result is { 42, 24 }

Bạn có thể đưa ra một số lời giải thích xung quanh những gì mã của bạn làm, cách nó trả lời câu hỏi và một số cách sử dụng ví dụ?
Enigmativity

@Enigmativity, nó thực hiện chính xác những gì đã được hỏi, câu hỏi là đề xuất một số từ điển hỗ trợ trùng lặp, vì vậy tôi đã đề nghị tạo một trình bao bọc xung quanh từ điển .net sẽ hỗ trợ chức năng này và như một ví dụ đã tạo ra trình bao bọc đó, như một phần thưởng có thể xử lý null làm chìa khóa (chắc chắn ngay cả khi đó là một thực tiễn tồi), cách sử dụng khá đơn giản: var dictionary = new OpenDictionary<string, int>(); dictionary.Add("1", 1); // The next line won't throw an exception; dictionary.Add("1", 2); dictionary.TryGetEntries("1", out List<int> result); // result is { 1, 2 }
Alexander Tolstikov

Bạn có thể thêm chi tiết vào câu trả lời của bạn?
Enigmativity

@Enigmativity, nếu bạn có ý với câu trả lời ban đầu, thì chắc chắn
Alexander Tolstikov

-1

Bạn có thể định nghĩa một phương thức để xây dựng khóa chuỗi Compound mỗi khi bạn muốn sử dụng từ điển u phải sử dụng phương thức này để xây dựng khóa của bạn chẳng hạn:

private string keyBuilder(int key1, int key2)
{
    return string.Format("{0}/{1}", key1, key2);
}

cho việc sử dụng:

myDict.ContainsKey(keyBuilder(key1, key2))

-3

Các khóa trùng lặp phá vỡ toàn bộ hợp đồng của Từ điển. Trong từ điển, mỗi khóa là duy nhất và được ánh xạ tới một giá trị duy nhất. Nếu bạn muốn liên kết một đối tượng với một số lượng đối tượng bổ sung tùy ý, đặt cược tốt nhất có thể là một cái gì đó tương tự như một Bộ dữ liệu (theo cách nói chung là một bảng). Đặt các khóa của bạn trong một cột và các giá trị của bạn trong cột khác. Điều này chậm hơn đáng kể so với từ điển, nhưng đó là sự đánh đổi của bạn vì mất khả năng băm các đối tượng chính.


5
Không phải toàn bộ việc sử dụng Từ điển để đạt được hiệu suất sao? Sử dụng Bộ dữ liệu có vẻ không tốt hơn Danh sách <KeyValuePair <T, U >>.
Doug

-4

Ngoài ra điều này là có thể:

Dictionary<string, string[]> previousAnswers = null;

Bằng cách này, chúng ta có thể có các phím duy nhất. Hy vọng điều này làm việc cho bạn.


OP yêu cầu một từ điển cho phép các khóa trùng lặp.
Skaparate

-10

Bạn có thể thêm các khóa giống nhau với trường hợp khác nhau như:

key1
Key1
KEY1
KeY1
kEy1
keY1

Tôi biết là câu trả lời giả, nhưng làm việc cho tôi.


4
Không, nó không làm việc cho bạn. Từ điển cho phép tra cứu rất nhanh - cũng được phân loại là O (1) - theo khóa, Bạn mất điều đó khi bạn thêm nhiều khóa khác nhau, vì làm thế nào để bạn lấy chúng? Hãy thử mọi kết hợp chữ hoa / chữ thường? Cho dù bạn làm điều đó như thế nào, hiệu suất sẽ không phải là tìm kiếm từ điển đơn, bình thường. Đó là những thiếu sót khác, rõ ràng hơn như giới hạn giá trị trên mỗi khóa, tùy thuộc vào số lượng ký tự có thể nâng cấp trong khóa.
Eugene Beresovsky
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.