D中的简单集实现?

时间:2011-12-11 01:41:37

标签: set containers d phobos

我在D的标准库中寻找Set实现,我只找到了这些:

  • 二叉堆
  • 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中的元素。这可行,但我得到编译错误:

  

错误: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?

4 个答案:

答案 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");