我应该使用哪种数据结构?

4
我有一个问题,我需要将两个输入映射到一个输出。
我知道字典是一种通用类型的线性映射:
对于每个x(键),可能存在y(值)
我需要的是多维映射:
对于每个x,y(键),可能存在z(值)
但当然,关键是我需要支持通用类型和动态大小。
这种数据结构在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;
            }
        }
    }
}

看起来在回答中重新发明轮子是占上风的。这是我迄今为止想出来的代码,但我觉得应该有更好的方法,比如一个矩阵之类的东西。


键的类型对于x和y是否相同?您能解释一下何时需要用泛型进行键的定义吗?异构键呢? - DarthVader
@DarthVader,在某些情况下,键的类型可能相同,但并非总是如此。 - zzzzBov
我想我也应该指定键的类型将特定于多维对象的实例。理想情况下,我希望能够编写new Dictionary3D<Foo,Bar,Baz>();并且它能像new Dictionary3D<int,int,bool>();一样正常工作。 - zzzzBov
https://dev59.com/sHRB5IYBdhLWcg3wNk53, https://dev59.com/T3M_5IYBdhLWcg3w6HzT - zzzzBov
6个回答

4

关于什么呢?

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

??


在尝试创建一个充当包装器的自定义类后,我决定为了创建新的 Tuples 所需的代码量太少,真的不值得这样折腾。 - zzzzBov

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方法。


哎呀,抱歉,我不知道那个。 - mephisto123

1

Tuple 可能是你想要的:

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

或者对于泛型:

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

关于 Tuple 的参考,请查看此处

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

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

如需参考,请点击此处


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);
        }
    }
}

你也可以将它变成通用的,但这是一个简单版本。

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


1

0

我认为你需要一个类型安全的异构容器,它由字典支持。在这种情况下,你将不得不重写IDictionary并拥有自己的实现。不幸的是,除非你遵循其他答案或找到解决方法,否则没有可用的类可以使用。

参见Joshua bloch,在这种情况下,你基本上可以将任何类型作为键存储。但是你也可以限制它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接