2017-10-06 1 views
2

私は、封じ込めチェックと追加/削除メソッド(例えばHashSet<T>Tがうまく実装されていればO(1)に近づいています)しかしそれにも命令があります。インデックス化されたアクセスを意味するものではありません。つまり、繰り返し処理すると、要素の順序は、要素を追加した順序と同じになります。コレクションが重複せず、順序があり、封じ込めチェックと追加/削除が高速です。

C#のようなものがありますか? HashSet<T>でもトリックはしますか?(私はHashSet<T>HashSet<T>.GetEnumeratorを確認し、MSDN上の情報を見つけることができませんでした。)

ない場合、私は内部HashSet<T>と内部LinkedList<T>を含むクラスでそれを実装することを考えていました。 HashSet<T>は、LinkedList<T>が列挙子を公開している間、追加、削除、包含チェックを公開します。

+0

'HashTable'は何でしょうか?彼らの実装ですか – DiskJunky

+0

あなたの提案された実装では、O(1)ではなく、O(n)個のアイテムが削除されます。 – Servy

+0

[OrderedDictionary](https://msdn.microsoft.com/en-us/library/system.collections.specialized.ordereddictionary.aspx)はオプションです。 – Blorgbeard

答えて

0

あなたはOrderedDictionaryを探しているようです。

唯一の欠点は、ジェネリックをサポートしていないことですが、簡単にラッパーを作成したり、必要な型に値をキャストすることができます。

EDIT:コメントの中に参照さ@Blorgbeardとして、あなたはあなたの正確な要件を満たしている(そして正確にLinkedList<T>HashSet<T>でこれを実装)another answerで「OrderedSet」の実装を見つけることができる、と役に立つかもしれません君は。ここで

は(クレジットは、元の作者に行く、ではない私

public class OrderedSet<T> : ICollection<T> 
{ 
    private readonly IDictionary<T, LinkedListNode<T>> m_Dictionary; 
    private readonly LinkedList<T> m_LinkedList; 

    public OrderedSet() 
     : this(EqualityComparer<T>.Default) 
    { 
    } 

    public OrderedSet(IEqualityComparer<T> comparer) 
    { 
     m_Dictionary = new Dictionary<T, LinkedListNode<T>>(comparer); 
     m_LinkedList = new LinkedList<T>(); 
    } 

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

    public virtual bool IsReadOnly 
    { 
     get { return m_Dictionary.IsReadOnly; } 
    } 

    void ICollection<T>.Add(T item) 
    { 
     Add(item); 
    } 

    public bool Add(T item) 
    { 
     if (m_Dictionary.ContainsKey(item)) return false; 
     LinkedListNode<T> node = m_LinkedList.AddLast(item); 
     m_Dictionary.Add(item, node); 
     return true; 
    } 

    public void Clear() 
    { 
     m_LinkedList.Clear(); 
     m_Dictionary.Clear(); 
    } 

    public bool Remove(T item) 
    { 
     LinkedListNode<T> node; 
     bool found = m_Dictionary.TryGetValue(item, out node); 
     if (!found) return false; 
     m_Dictionary.Remove(item); 
     m_LinkedList.Remove(node); 
     return true; 
    } 

    public IEnumerator<T> GetEnumerator() 
    { 
     return m_LinkedList.GetEnumerator(); 
    } 

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

    public bool Contains(T item) 
    { 
     return m_Dictionary.ContainsKey(item); 
    } 

    public void CopyTo(T[] array, int arrayIndex) 
    { 
     m_LinkedList.CopyTo(array, arrayIndex); 
    } 
} 
+0

O(n)の追加と削除が行われます。 – Servy

+0

@Servyあなたの主張の証拠はありますか?あなたは鍵で取り除いたときにのみ正しいです。他の操作については、O(1)です。 –

+0

アイテムを追加するには、O(n)操作であるキーペアのインデックスの配列リストを検索する必要があります。ソースコードを見れば、あなた自身で見ることができます。それがO(1)だと主張する証拠はありますか? – Servy

関連する問題