.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相等但压缩失败的单词发生了什么,有人能帮助我更好地理解吗?它们将如何存储在词典中?字典自动处理哈希值冲突。不用担心,你可以使用字典,其中键是构造的频率字符串(字母按字母顺序排序+频率)。该列表将包含所有相应的