我应该使用什么数据结构?

时间:2011-10-21 21:50:18

标签: c# data-structures

我有一个问题,我需要将两个输入映射到单个输出。

我知道字典是一般类型的线性映射:

  

对于每个x(key),可能有y(value

我需要的是多维映射:

  

对于每个x,y(key),可能有一个z(value

但当然,踢球者是我需要它来支持通用打字并且动态调整大小。

这个数据结构是否存在于C#中,还是我必须创建一个字典字典?如果我不需要,我宁愿不重新发明轮子。


重新发明轮子:

using System;
using System.Collections.Generic;
using System.Text;

namespace zlib.Collections
{
    public class Dictionary3D<Tx, Ty, Tz>
    {
        private Dictionary<Tuple<Tx, Ty>, Tz> _dict = new Dictionary<Tuple<Tx, Ty>, Tz>();

        public void Add(Tx x, Ty y, Tz z)
        {
            _dict.Add(Tuple.Create<Tx, Ty>(x, y), z);
        }

        public void Clear()
        {
            _dict.Clear();
        }

        public bool ContainsKey(Tx x, Ty y)
        {
            return _dict.ContainsKey(Tuple.Create<Tx, Ty>(x, y));
        }

        public bool ContainsValue(Tz z)
        {
            return _dict.ContainsValue(z);
        }

        public Dictionary<Tuple<Tx, Ty>, Tz>.Enumerator GetEnumerator()
        {
            return _dict.GetEnumerator();
        }

        public bool Remove(Tx x, Ty y)
        {
            return _dict.Remove(Tuple.Create<Tx, Ty>(x, y));
        }

        public bool TryGetValue(Tx x, Ty y, out Tz z)
        {
            return _dict.TryGetValue(Tuple.Create<Tx, Ty>(x, y), out z);
        }

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

        public Dictionary<Tuple<Tx,Ty>,Tz>.KeyCollection Keys
        {
            get
            {
                return _dict.Keys;
            }
        }

        public Dictionary<Tuple<Tx, Ty>, Tz>.ValueCollection Values
        {
            get
            {
                return _dict.Values;
            }
        }

        public Tz this[Tx x, Ty y]
        {
            get
            {
                return _dict[Tuple.Create<Tx, Ty>(x, y)];
            }
            set
            {
                _dict[Tuple.Create<Tx, Ty>(x, y)] = value;
            }
        }
    }
}

似乎重新发明轮子在响应中胜出。这是我到目前为止提出的代码,但我觉得应该有一个更好的方法,比如matrix或其他什么。

6 个答案:

答案 0 :(得分:4)

怎么样

   Dictionary<Tuple<T,K>,Tuple<L,J>> 

...

答案 1 :(得分:1)

如果我找到了你,那就是你需要的:

class Key<Tx, Ty>
{
    public Tx x;
    public Ty y;

    public Key(Tx x, Ty y)
    {
        this.x = x;
        this.y = y;
    }
}

Dictionary<Key<Tx, Ty>, Tz> d;

是的,如果在评论中提到,你必须在Key类中实现HashCode和Equals。

答案 2 :(得分:1)

元组可能就是你想要的:

var population = new Tuple< string, int>("New York", 7891957);

或用于泛型:

var population = new Tuple< S, T>("New York", 7891957);

元组参考外观here

此外,如果您想要例如用户词典,您可以这样做:

using DictOfDict = Dictionary< X, Dictionary< Y, Z>> ;

参考外观here

答案 3 :(得分:1)

Chuck Jazdzewski写了一段时间后写的PolyDictionary如果你使用Tuple&lt; T1,T2&gt;可能会得到你想要的东西。作为关键。实际上,它只是Dictionary&lt; object,object&gt;的包装器。但它确实可以解决问题。看看他关于这个主题的博客系列:

答案 4 :(得分:1)

这个怎么样:

class Dict3D
{
    private Dictionary<KeyValuePair<object,object>, object> innnerDict= new Dictionary<KeyValuePair<object,object>, object>();

    public object Get(object key1, object key2)
    {
        KeyValuePair<object,object> bigKey = new KeyValuePair<object, object>(key1, key2);
        if (innnerDict.ContainsKey(bigKey))
        {
            return innnerDict[bigKey];
        }
        return null;
    }

    public void Set(object key1, object key2, object somevalue)
    {
        KeyValuePair<object, object> bigKey = new KeyValuePair<object, object>(key1, key2);
        if (innnerDict.ContainsKey(bigKey))
        {
            innnerDict[bigKey] = somevalue;
        }
        else
        {
            innnerDict.Add(bigKey, somevalue);
        }
    }
}

你也可以把它作为通用的,但这是一个简单的版本。

我想答案意味着如果你想要一个干净的解决方案,你(或其他人)可能不得不重新发明轮子。

答案 5 :(得分:0)

我认为你需要一个类型安全的异构容器,它由字典支持。在这种情况下,您将必须覆盖IDictionary并拥有自己的impl。不幸的是,除非你按照其他答案或找到一个解决方法,否则你不能使用任何课程。

在这种情况下,请参阅Joshua bloch,您基本上可以将任何类型存储为密钥。但是你也可以限制它。