.net 字典的存取时间是多少<;字典<;字符,int>;,列表<;字符串>>,还是O(1)?

.net 字典的存取时间是多少<;字典<;字符,int>;,列表<;字符串>>,还是O(1)?,.net,generics,dictionary,big-o,iequalitycomparer,.net,Generics,Dictionary,Big O,Iequalitycomparer,我想用Dictionary实现一个算法,在字典中查找字谜词 由于我需要为该词典实现自定义的EqualityComparer,访问时间是否仍然是O(1),即大O(1) 第二个问题,作为EqualityComparer的一部分,我还需要实现GetHashCode()。为字典确定GetHashCode()的有效方法是什么 我刚想出这个方法,有没有更好的选择 public int GetHashCode(Dictionary<char, int> obj) { unc

我想用
Dictionary
实现一个算法,在字典中查找字谜词

由于我需要为该词典实现自定义的
EqualityComparer
,访问时间是否仍然是O(1),即大O(1)

第二个问题,作为
EqualityComparer
的一部分,我还需要实现
GetHashCode()
。为
字典
确定
GetHashCode()
的有效方法是什么

我刚想出这个方法,有没有更好的选择

public int GetHashCode(Dictionary<char, int> obj)
    {
        unchecked
        {
            int hashCode = 17;
            foreach (var item in obj)
            {
                hashCode += 23 * item.Key.GetHashCode();
            }
            return hashCode;
        }
    }
public int GetHashCode(字典obj)
{
未经检查
{
int hashCode=17;
foreach(obj中的var项目)
{
hashCode+=23*item.Key.GetHashCode();
}
返回哈希码;
}
}

任何忠告都将不胜感激。谢谢

如何将单词“need”转换为字符串“d1e2n1”,而不是使用字典作为键?为了构建这个字符串,可以使用二叉树。字符将用作键,字符计数用作值。二叉树是按键自动排序的,而字典则不是这样

通过将二进制表示形式与XOR操作相结合,可以从单个散列值计算组合散列值。使用C#,您可以执行以下操作:

public override int GetHashCode()
{
    // Combine hashcode of a and b
    return a.GetHashCode() ^ b.GetHashCode();
}

在未排序的列表中查找条目是一个O(n)操作。如果使用二进制搜索,则在排序列表中查找条目是一个O(log(n))操作

在字典的列表中查找单词是一个O(1+n)操作,与O(n)操作相同,或者是一个O(1+log(n))操作,与O(log(n))操作相同


编辑:

下面是一个可能的实现:

var anagrams = new Dictionary<string, List<string>>();
foreach (string word in words) {
    string key = GetFrequency(word);
    List<string> list;
    if (anagrams.TryGetValue(key, out list)) {
        list.Add(word);
    } else {
        list = new List<string> { word };
        anagrams.Add(key, list);
    }
}
。。。生成此输出

a1e1m1t1:
    meat
    meta
    team

a1n1t1:
    Nat
    tan

d1e2n1:
    eden
    need

编辑#2:

下面是Ben Voigt建议的频率计算

private string GetFrequencyByBenVoigt(string word)
{
    char[] chars = word.ToLower().ToCharArray();
    Array.Sort(chars);
    return new string(chars);
}
测试结果将是

aemt:
    meat
    meta
    team

ant:
    Nat
    tan

deen:
    eden
    need

如何将单词“need”转换为字符串“d1e2n1”,而不是使用字典作为键?为了构建这个字符串,可以使用二叉树。字符将用作键,字符计数用作值。二叉树是按键自动排序的,而字典则不是这样

通过将二进制表示形式与XOR操作相结合,可以从单个散列值计算组合散列值。使用C#,您可以执行以下操作:

public override int GetHashCode()
{
    // Combine hashcode of a and b
    return a.GetHashCode() ^ b.GetHashCode();
}

在未排序的列表中查找条目是一个O(n)操作。如果使用二进制搜索,则在排序列表中查找条目是一个O(log(n))操作

在字典的列表中查找单词是一个O(1+n)操作,与O(n)操作相同,或者是一个O(1+log(n))操作,与O(log(n))操作相同


编辑:

下面是一个可能的实现:

var anagrams = new Dictionary<string, List<string>>();
foreach (string word in words) {
    string key = GetFrequency(word);
    List<string> list;
    if (anagrams.TryGetValue(key, out list)) {
        list.Add(word);
    } else {
        list = new List<string> { word };
        anagrams.Add(key, list);
    }
}
。。。生成此输出

a1e1m1t1:
    meat
    meta
    team

a1n1t1:
    Nat
    tan

d1e2n1:
    eden
    need

编辑#2:

下面是Ben Voigt建议的频率计算

private string GetFrequencyByBenVoigt(string word)
{
    char[] chars = word.ToLower().ToCharArray();
    Array.Sort(chars);
    return new string(chars);
}
测试结果将是

aemt:
    meat
    meta
    team

ant:
    Nat
    tan

deen:
    eden
    need


基于容器内容的哈希代码在容器中的项目计数中将为
O(n)
。您可以将字典包装为另一种类型并缓存哈希代码,这样它只需要计算一次。。。但是我可以想出几种比字典更有效的方法来存储这些数据。

基于容器内容的哈希代码在容器中的项目计数中将是
O(n)
。您可以将字典包装为另一种类型并缓存哈希代码,这样它只需要计算一次。。。但是我可以想出几种比字典更有效的方法来存储数据。

字典的访问时间接近O(1),但事实并非如此。在理想情况下(良好的分布/很少的碰撞),您可以将其视为O(1)。在由于GetHashCode值的低方差而导致大量冲突的情况下,访问时间会降低并接近O(N)

字典的访问时间接近O(1),但并不完全如此。在理想情况下(良好的分布/很少的碰撞),您可以将其视为O(1)。在由于GetHashCode值的低方差而导致大量冲突的情况下,访问时间会降低并接近O(N)

具有可变键的字典是一个痛苦的秘诀,但它们不是典型的.net代码中最常见的字典键吗?Ben?最常见的字典键不是什么?不,字典和其他集合类型不经常用作其他字典的键。糟糕,我错误地将您的注释理解为不可变!所以我想知道!是的,我明白你的意思。带可变键的字典是一个痛苦的秘诀,但它们不是典型的.net代码中最常见的字典键吗?Ben?最常见的字典键不是吗?不,字典和其他集合类型不经常用作其他字典的键。糟糕,我错误地将您的注释理解为不可变!所以我想知道!是的,我明白你的意思。总的来说,这是个好主意,但就“deen”(即按字母顺序排列字母并保留重复)怎么样?这是可能的,在将CharacterHashMap作为分析中单词的字典后,我可以将其设置为字符串并将其作为键。但是在我得到字符串表示之前需要对CharacterHashMap进行排序。如果两个不是字谜但HashCode相等但压缩失败的单词发生了什么,有人能帮助我更好地理解吗?它们将如何存储在词典中?字典自动处理哈希值冲突。不用担心,你可以使用字典,其中键是构造的频率字符串(字母按字母顺序排序+频率)。该列表将包含所有相应的