最好的c ++容器来剥离物品?

时间:2009-01-29 00:17:55

标签: c++ list vector set containers

我有一个文件列表(存储为c样式字符串),我将执行搜索,我将删除那些与我的参数不匹配的文件。为此目的使用的最佳容器是什么?我想的就是现在。请注意,文件列表永远不会大于初始化时的文件列表。我只会从容器中删除。

6 个答案:

答案 0 :(得分:3)

我肯定不会使用一套 - 你不需要对它进行排序所以没有必要使用一套。 Set通常被实现为自平衡树,并且在您的情况下不需要自平衡算法。

如果您要进行一次此操作,我会使用带有remove_if的std :: vector(来自< algorithm>),然后进行擦除。如果您之前没有使用过remove_if,它会做什么,并将所有相关项目移除,覆盖过程中不相关的项目。您必须使用擦除来跟随它以减小矢量的大小。像这样:

std::vector<const char*> files;
files.erase(remove_if(files.begin(), files.end(), RemovePredicate()), files.end());

如果要利用其O(1)删除时间属性,编写代码以使用std :: list执行相同的操作将会更加困难。看到你正在进行这种一次性操作,可能花费的时间很少,你甚至都不会注意到它,我建议这样做,因为这是最简单的方法。

说实话,我认为你不会在std :: list和std :: vector方法之间看到那么大的差异。向量方法只复制每个值一次,因此它实际上非常快,但占用的空间更少。在我看来,如果你在整个应用程序的生命周期中进行大量的添加和删除,那么进入std :: list并使用三倍的空间是非常合理的。

答案 1 :(得分:2)

std :: set中的元素必须是唯一的,因此除非文件名是全局唯一的,否则这将不适合您的需要。

我可能会推荐一个std :: list。

答案 2 :(得分:1)

来自SGI

  • vector是一个序列,支持对元素的随机访问,最后元素的恒定时间插入和删除,以及在开头或中间插入和删除元素的线性时间。 / p>

  • list是双重链接列表。也就是说,它是一个支持向前和向后遍历的序列,以及(分期)在开始或结束时或在中间插入和删除元素的(摊销)。

  • slist是一个单链表:一个列表,其中每个元素链接到下一个元素,但不链接到前一个元素。也就是说,它是一个支持向前但不向后遍历的序列,并且(摊销)恒定时间插入和删除元素。

  • Set是一个Sorted Associative Container,用于存储Key类型的对象。 Set是一个简单关联容器,意味着它的值类型及其键类型是Key。它也是一个唯一的关联容器,意味着没有两个元素是相同的。

  • Multiset是一个Sorted Associative Container,用于存储Key类型的对象。 Multiset是一个简单关联容器,意味着它的值类型及其键类型是Key。它也是一个多关联容器,意味着两个或多个元素可能相同。

  • Hash_set是一个哈希关联容器,用于存储Key类型的对象。 Hash_set是一个简单关联容器,意味着它的值类型及其键类型是Key。它也是一个唯一的关联容器,意味着使用Binary Predicate EqualKey没有两个元素相等。

  • Hash_multiset是一个哈希关联容器,用于存储Key类型的对象。 Hash_multiset是一个简单的关联容器,意味着它的值类型及其键类型是Key。它也是一个多关联容器,意味着两个或多个元素可以使用Binary Predicate EqualKey进行比较。

(某些容器已被省略。)

如果你想要的是一个快速且不包含多个相同键的容器,我会选择hash_sethash_multiset如果您这样做,setmultiset,如果您希望对字符串进行排序,或listslist,如果您希望字符串保持其插入顺序。

在您构建列表/集后,使用remove_if根据您的条件过滤掉您的商品。

答案 3 :(得分:0)

我将首先抛出向量,因为它是一个顺序容器。设置,我相信接近顺序或散列。我会避免这种情况。一个双向链表,stl列表就是其中之一,有两个指针和节点。基本上,要删除一个项目,它会打破链条,然后用指针重新加入这两个部分。

答案 4 :(得分:0)

假设您的搜索条件不依赖于文件名(即您搜索内容,文件大小等),因此您无法使用集合,我会使用list。构建整个列表需要O(N),每次删除需要O(1)。

如果你想让它更快,并且不坚持使用现成的STL容器,我会:

  1. 使用vector
  2. 使用false delete删除,即。将项目标记为已删除
  3. 当已删除/所有项目的比率超过特定阈值时,我会使用remove_if
  4. 过滤项目

    这应该为您提供最佳的空间/时间/缓存性能。 (虽然你应该对它进行描述以确定)

答案 5 :(得分:0)

您可以使用两个列表/向量/其他:

using namespace std;

vector<const char *> files;

files.push_back("foo.bat");
files.push_back("bar.txt");

vector<const char *> good_files;  // Maybe reserve elements given files.size()?

for(vector<const char *>::const_iterator i = files.begin(); i != files.end(); ++i) {
    if(file_is_good(*i)) {
        new_files.push_back(*i);
    }
}