在 O(1) 时间内实现具有基于键和基于索引的访问的哈希表

发布于 2024-12-06 22:39:43 字数 1776 浏览 1 评论 0 原文

有一个名为 NameObjectCollectionBase 的数据结构我试图理解.NET。

基本上,它允许输入任意字符串 =>对象键/值对,键和值都可能为空。一个密钥可以被多个对象使用。通过基于索引和基于字符串的访问来授予访问权限,而基于字符串的访问仅返回具有指定键的第一个值。

他们承诺,

add(string, object)        O(1) if no relocation, O(n) otherwise
clear                      O(1)
get(int)                   O(1) corresponds to getkey(int)
get(string)                O(1) returns first object found with given key
getallkeys                 O(n) if objects share a key, it is returned that many times
getallvalues               O(n)
getallvalues(type)         O(n) returns only objects of a given type
getkey(int)                O(1) corresponds to get(int)
haskeys                    O(1) if there are objects with a non-null key
remove(string)             O(n) remove all objects of a given key
removeat(int)              O(n)
set(int, object)           O(1) 
set(string, object)        O(1) sets the value of the first found object with given key
getenumerator              O(1) enumerator over keys
copyto(array, int)         O(n) 

基于索引的访问与插入顺序无关。但是,get(int)getkey(int) 必须彼此对齐。

我想知道如何实现该结构。在 O(1) 时间内同时允许基于索引和基于键的访问似乎实现起来并不容易。他们在 MSDN 页面上声明“此类的底层结构是哈希表”。但是,C# 哈希表不允许每个键有多个值,也不允许有空键。

将其实现为 Dictionary 似乎不是解决方案,因为 get(string) 将是 O(1) 但 get(int) 不是,因为您必须遍历所有键找出哪个钥匙里有多少个物品。

将其实现为两个单独的列表,其中一个是用于键的简单 List 和一个用于 ListDictionary< 组合的值。 string, int> 将每个键指向第一个值的索引,这将允许在 O(1) 中进行两种类型的访问,但不允许以有效的方式删除,因为所有索引都必须在哈希表(在 O(n) 中是可能的,但似乎不是最好的解决方案)。或者是否有更有效的方法来删除条目?

这样的数据结构如何实现呢?

There is a data structure called NameObjectCollectionBase in .NET which I'm trying to understand.

Basically, it allows to enter arbitrary string => object key/value-pairs with both the possibility of the key and the value being null. A key may be used by multiple objects. Access is granted through both an index-based and a string-based access, whereas the string-based access returns only the first value with the specified key.

What they promise, is

add(string, object)        O(1) if no relocation, O(n) otherwise
clear                      O(1)
get(int)                   O(1) corresponds to getkey(int)
get(string)                O(1) returns first object found with given key
getallkeys                 O(n) if objects share a key, it is returned that many times
getallvalues               O(n)
getallvalues(type)         O(n) returns only objects of a given type
getkey(int)                O(1) corresponds to get(int)
haskeys                    O(1) if there are objects with a non-null key
remove(string)             O(n) remove all objects of a given key
removeat(int)              O(n)
set(int, object)           O(1) 
set(string, object)        O(1) sets the value of the first found object with given key
getenumerator              O(1) enumerator over keys
copyto(array, int)         O(n) 

Index-based access does have nothing to do with the insertion order. However, get(int) and getkey(int) have to line up with each other.

I'm wondering how the structure may be implemented. Allowing both index and key-based access at the same time in O(1) seems not trivial to implement. They state on the MSDN page that "The underlying structure for this class is a hash table." However, the C# Hash tables don't allow multiple values per key and alo not null-keys.

Implementing it as a Dictionary<string, List<object> does not seem to be the solution as get(string) would be O(1) but get(int) not since you have to traverse all keys to find out which key has how many items in it.

Implementing it as two separated lists where one is a simple List<string> for the keys and a List<Object> for the values in combination of a Dictionary<string, int> which points for each key to the index of the first value would allow both types of access in O(1) but would not allow removing in an efficient way since all indices would have to be updated in the hashtable (would be possible in O(n) but doesn't seem to be the best solution). Or would there be a more efficient way to remove an entry?

How could such a data structure be implemented?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

猫九 2024-12-13 22:39:43

NameObjectCollectionBase 使用 Hashtable 和 Arraylist 来管理条目。你自己看看吧!

Microsoft 提供 .NET 库的参考源代码,并且可以集成到 Visual Studio 中:

http://referencesource.microsoft.com/< /a>

您甚至可以调试 .NET 库:

http://msdn.microsoft.com/en-us/library/cc667410(VS.90).aspx

或者您可以获取免费反编译器 dotPeek 的副本:

http://www.jetbrains.com/decompiler/

NameObjectCollectionBase uses both a Hashtable and an Arraylist to manage the entries. Have a look for yourself!

Microsoft provides reference source code for .NET libraries and can be integrated into Visual Studio:

http://referencesource.microsoft.com/

You can even debug the .NET library:

http://msdn.microsoft.com/en-us/library/cc667410(VS.90).aspx

Or you can grab a copy of dotPeek, a free decompiler:

http://www.jetbrains.com/decompiler/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文