在当前任务中,我需要从数据库中读取大约10,000条记录(学生数据),并将其存储在容器中。现在,我需要选择容器来存储所有这些记录,以便生成报告。报告生成选项特定于供应商,因为一个供应商希望转储所有记录而不进行排序,而另一个供应商希望根据已排序的名称字段生成报告。我从末端选择了向量,因为我不需要在中间插入任何形式,并且对于第一种选择(报告不对字段进行排序)不需要搜索工作,但是对于第二种选择,有人可以建议我向量是否合适通过引入基于名称字段的排序来实现相同的目的。

以下是我在第23项scott meyers书(有效STL)中找到的一些有用的指针。我相信基于下面的信息,需要使用第二种选择的排序向量,但是我仍然希望有人在得出任何结论并开始编码之前对此有所了解。

项目23.考虑用排序的向量替换关联容器

“ **标准关联容器通常以平衡的二进制搜索树的形式实现。平衡的二进制搜索树是一种针对插入,擦除和查找的混合组合进行了优化的数据结构。也就是说,它是为执行某些操作的应用程序设计的插入,然后进行一些查找,然后进行更多插入,然后进行某些擦除,然后进行更多查找,然后进行更多插入或擦除,然后进行更多查找,等等。此事件序列的主要特征是插入,擦除和查找混合在一起。通常,无法预测树上的下一个操作是什么”

最佳答案

正如斯科特·迈耶斯(Scott Meyers)所建议的那样,std::vector是用于存储数据和操纵数据的非常好的容器(如果数据很大,则有例外)-不仅取决于元素数量,而且元素大小也很重要。

您可以通过不操纵数据本身-而是操纵该数据的索引来减小要操纵的数据大小。

假设您已经从文件中读取了向量:

struct Element { .... };
std::vector<Element> data;
readData(someFile);


您可以通过创建这样的索引向量来生成这些记录的“自然顺序”(请参见iota on cppreference):

using indices = std::vector<std::size_t>;
indices naturalOrder(data.size());
std::iota(naturalOrder.begin(), naturalOrder.end(), 0); // filled with 0,1,2,...


要使用此索引打印记录-定义这样的算法:

template <typename Container, typename Indices, typename Operation>
void for_erach(Container&& container, const Indices& indices, Operation&& op)
{
    for (auto i: indices)
        op(container[i]);
}

// print in natural order
for_each(data, naturalOrder, [] (auto const& e) {
    std::cout << e << std::endl;
});


要排序,只需对索引排序:

Indices sorterdByXOrder = naturalOrder;
auto lessX = [&data](auto i, auto j) { return data[i].x < data[j].x; };
std::sort(sorterdByXOrder.begin(), sorterdByXOrder.end(), lessX);
// print in sorted by x  order
std::cout << "Sorted by x:" << std::endl;
for_each(data, sorterdByXOrder , [] (auto const& e) {
    std::cout << e << std::endl;
});


仅具有例如element.y == 7-执行以下操作:

Indices onlyY7Order;
auto yIs7 = [&data](auto i) { return data[i].y == 7; };
std::copy_if(naturalOrder.begin(), naturalOrder.end(),
          std::back_inserter(onlyY7Order),  yIs7);


如果您在将整个数据读取到std::vector时遇到性能问题-您可以尝试使用std::deque-在某些情况下可能会更快。我呈现的其余代码不会更改-因为std::dequestd::vector具有非常相似的接口...

关于c++ - 选择要插入多个数据库记录的容器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32857028/

10-16 07:14
查看更多