D 中的简单 Set 实现?
我在 D 的标准库中寻找 Set 实现,我只找到了这些:
- BinaryHeap
- RedBlackTree
如果我只能弄清楚如何使用它们,那么这两个都可以正常工作。我从 RedBlackTree 开始(因为我已经熟悉它们的工作原理),这就是我想到的:
auto rbt = redBlackTree!string();
foreach(s; setOfStrings) {
rbt.insert(s);
}
foreach(s; rbt) {
if (s[0 .. 3] == "sth") {
rbt.removeKey(s);
}
}
我知道我可以在第一个 foreach 中完成条件,但这只是一个例子,表明我需要从 Set 中添加和删除元素。这可行,但我收到编译错误:
错误:模板 std.container.RedBlackTree!(string).RedBlackTree.removeKey(U) if (isImplicitlyConvertible!(U,Elem)) 与任何函数模板声明都不匹配
错误:模板 std.container.RedBlackTree!(string).RedBlackTree.removeKey(U) if (isImplicitlyConvertible!(U,Elem)) 无法从参数类型推导出模板函数!()(string
I不需要红黑树(任何没有重复的东西),而且速度也不太重要,我可以做这样的事情:
string[] arr;
foreach(s; setOfStrings) {
// check for duplicate code here...
arr ~= s;
}
for(int i = 0; i < arr.length; i++) {
if (s[0 .. 3] == "sth") {
arr = arr[0 .. i] ~ arr[i + 1 .. $];
i++;
}
}
标准库中有没有简单的集合?
I was fishing around in D's standard library looking for a Set implementation, and I only found these:
- BinaryHeap
- RedBlackTree
These both would work fine, if I could only figure out how to use them. I started with the RedBlackTree (because I'm already familiar with how they work), and this is what I came up with:
auto rbt = redBlackTree!string();
foreach(s; setOfStrings) {
rbt.insert(s);
}
foreach(s; rbt) {
if (s[0 .. 3] == "sth") {
rbt.removeKey(s);
}
}
I know I could have done the condition in the first foreach, but it's just an example showing that I need to add and remove elements from the Set. This would work, but I get compile errors:
Error: template std.container.RedBlackTree!(string).RedBlackTree.removeKey(U) if (isImplicitlyConvertible!(U,Elem)) does not match any function template declaration
Error: template std.container.RedBlackTree!(string).RedBlackTree.removeKey(U) if (isImplicitlyConvertible!(U,Elem)) cannot deduce template function from argument types !()(string
I don't need a red-black tree (anything without duplicates), and speed isn't too important. I could do something like this:
string[] arr;
foreach(s; setOfStrings) {
// check for duplicate code here...
arr ~= s;
}
for(int i = 0; i < arr.length; i++) {
if (s[0 .. 3] == "sth") {
arr = arr[0 .. i] ~ arr[i + 1 .. $];
i++;
}
}
Is there anything in the standard library for a simple Set?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
RedBlackTree
是 Phobos 的集合实现。removeKey
遇到的问题是它是可变的。它将需要删除一个键数组或多个键(例如removeKey(arr)
或removeKey(key1, key2, key3)
)。string
是一个不可变字符数组,因此它尝试使用char
而不是string
实例化removeKey
,这不会不起作用,因为你的树保存的是字符串,而不是字符。如果您处理的是整数或任何其他非数组类型的RedBlackTree
,则不会遇到此类问题。您需要做的是要么给它一个字符串数组,要么直接实例化它,即
removeKey([s])
或removeKey!string(s)
。顺便说一句,std.container 已经根据其数据结构而不是其用途来命名其容器类型。所以,当你说你不需要红黑树时,这是不太正确的。你想要一套。你只是不关心它是如何实现的。实现集合的两种典型方法涉及使用红黑树或哈希表。因此,
RedBlackTree
为您提供了一种拥有集合的方法。只是它是根据其数据结构命名的,而不是您如何使用它,因此如果您在 std.container 中查找容器名称Set
,您将找不到它。编辑:此问题存在错误报告 ,并且已提交修复。因此,在 dmd 的未来版本中,应该可以将
string
传递给removeKey
,而不必直接实例化它或传递string
在数组内部。RedBlackTree
is Phobos' set implementation. The problem that you're running into withremoveKey
is the fact that it's variadic. It will take either an array of keys to remove or multiple keys (e.g.removeKey(arr)
orremoveKey(key1, key2, key3)
).string
is an array of immmutable chars, so it tries to instantiateremoveKey
withchar
instead ofstring
, which doesn't work, because your tree holds strings, not chars. You wouldn't have this sort of problem if you were dealing with aRedBlackTree
of ints or any other non-array type.What you need to do is either give it an array of strings or to instantiate it directly i.e.
removeKey([s])
orremoveKey!string(s)
.By the way, std.container has gone the route of naming its container types based on their data structure rather than what they're used for. So, when you say that you don't need a red-black tree, that's not quite right. You want a set. You just don't care how it's implemented. The two typical ways to implement sets involve using either a red-black tree or a hash table. So,
RedBlackTree
gives you one way to have a set. It's just that its named after its data structure, not how you might use it, so if you're looking for a container nameSet
in std.container, you're not going to find it.EDIT: A bug report exists for this, and a fix has been submitted. So, in a future release of dmd, it should be possible to pass a
string
toremoveKey
without having to directly instantiate it or pass thestring
in inside an array.据我所知没有。
最好的选择是仅使用键的哈希表 (
bool[key] yourTable;
) 并忽略这些值。Not that I know of.
Your best bet is to just use a hashtable by the keys (
bool[key] yourTable;
) and ignore the values.我至少知道一个:http://www.dsource.org/projects/dcollections
I know of at least one: http://www.dsource.org/projects/dcollections
改进 Mehrdad 使用
bool[key]
的建议,您可以使用byte[0][key]
避免一些空间浪费。byte[0]
是一个大小为零的静态数组,因此它是一种不使用空间的类型。用法:Improving on Mehrdad's suggestion of using
bool[key]
, you can avoid some space wastage by usingbyte[0][key]
.byte[0]
is a static array of size zero, so it's a type that uses no space. Usage: