我在D的标准库中寻找Set实现,我只找到了这些:
如果我只能弄清楚如何使用它们,这两种方法都可以正常工作。我从RedBlackTree开始(因为我已经熟悉它们是如何工作的),这就是我想出来的:
auto rbt = redBlackTree!string();
foreach(s; setOfStrings) {
rbt.insert(s);
}
foreach(s; rbt) {
if (s[0 .. 3] == "sth") {
rbt.removeKey(s);
}
}
我知道我可以在第一个foreach中完成这个条件,但这只是一个示例,表明我需要添加和删除Set中的元素。这可行,但我得到编译错误:
错误:template std.container.RedBlackTree!(string).RedBlackTree.removeKey(U)if(isImplicitlyConvertible!(U,Elem))与任何函数模板声明不匹配
错误:template std.container.RedBlackTree!(string).RedBlackTree.removeKey(U)if(isImplicitlyConvertible!(U,Elem))无法从参数类型推导出模板函数!()(string
我不需要红黑树(任何没有重复的东西),速度不是太重要。我可以这样做:
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++;
}
}
标准库中是否有任何简单的Set?
答案 0 :(得分:7)
RedBlackTree
是Phobos的集合实现。您遇到removeKey
时遇到的问题是它是可变的。它需要删除一系列键或多个键(例如removeKey(arr)
或removeKey(key1, key2, key3)
)。 string
是一个包含immutable的字符数组,因此它尝试使用removeKey
而不是char
来实例化string
,这不起作用,因为您的树包含字符串,而不是字符。如果您处理的是RedBlackTree
整数或任何其他非数组类型,则不会出现此类问题。
您需要做的是给它一个字符串数组或直接实例化它,removeKey([s])
或removeKey!string(s)
。
顺便说一下,std.container已经开始根据数据结构命名其容器类型,而不是用于它们的用途。所以,当你说你不需要一棵红黑树时,那是不对的。你想要一套。你根本不在乎它是如何实现的。实现集合的两种典型方法涉及使用红黑树或哈希表。因此,RedBlackTree
为您提供了一种设置方法。它只是以它的数据结构命名,而不是你如何使用它,所以如果你在std.container中寻找一个容器名Set
,你就不会找到它。
编辑:此处存在bug report,并且已提交修复程序。因此,在将来的dmd版本中,应该可以将string
传递给removeKey
,而无需直接实例化它或在数组内传递string
。
答案 1 :(得分:4)
不是我知道的。
最好的办法是只使用密钥(bool[key] yourTable;
)使用散列表并忽略这些值。
答案 2 :(得分:1)
答案 3 :(得分:1)
改进Mehrdad关于使用bool[key]
的建议,您可以使用byte[0][key]
来避免一些空间浪费。 byte[0]
是一个大小为零的静态数组,因此它是一个不使用空格的类型。用法:
byte[0][string] mySet;
// Insert an element.
mySet["foo"] = (byte[0]).init;
// Lookup
assert("foo" in mySet);
// Remove
mySet.remove("foo");