【发布时间】:2014-06-26 22:37:29
【问题描述】:
我需要一些帮助来选择一种有效的算法来将向量中的元素放入预排序的桶中 - 或者理想地输出迭代器范围(因为我认为它们很有效)。下面的示例完全是人为的,但其想法是使用元素的键来确定输出桶。我不是在问如何按顺序排序,因为这是一个非常简单的简单调用问题(它可以根据键工作并重新排序元素)
std::sort(testVec.begin(), testVec.end(), comparator);
我在 coliru 上放了一个live example,它很容易修改和修复(不是那么容易,否则我不会问这个问题)。我也可以浏览这个排序列表中的元素,虽然键值相同,但将其附加到一个新的存储桶中,但我正在寻找更像 STL 的东西,现在上面闻起来有点像不得已而为 hack,最终的解决方案也需要高效,因为 testVec 可能很大并且对象的大小也很大。我不想修改 testvec - 所以它应该是不可变的。
理想情况下,我正在寻找某种能够吐出范围迭代器或同样有效的构造。实际对象很大,因此传递引用或移动它们确实是唯一的选择 - 我的实际对象(相当于 MyStr)是可移动的。某种 foreach 键、应用键谓词或我无法弄清楚的东西是我正在寻找的东西。我对下面的 3 个存储桶进行了硬编码,只是为了展示我需要能够达到的目标 - 这完全是一个 hack。
提前感谢您对此问题的任何帮助
#include <string>
#include <iostream>
#include <sstream>
#include <iterator>
#include <vector>
#include <algorithm>
struct MyStr
{
int key;
std::string strval;
MyStr(int key, const std::string& rStrVal)
: key(key)
, strval(rStrVal)
{}
// let stream operators be friend functions instead of members!
inline friend std::ostream& operator << (std::ostream& os, const MyStr& val) {
os << "key[" << val.key << "], strval['" << val.strval << "']";
return os;
}
bool operator < (const MyStr& str) const {
return (key > str.key);
}
};
int main()
{
std::vector <MyStr> testVec = {
MyStr(4, "key 4"),
MyStr(3, "key 3"),
MyStr(3, "key 3"),
MyStr(2, "key 2"),
MyStr(2, "key 2"),
MyStr(2, "key 2")
};
//auto comparator = [](const MyStr& lhs, const MyStr& rhs) {
// return lhs.key < rhs.key;
//};
std::vector <MyStr> foursBucket;
std::vector <MyStr> threesBucket;
std::vector <MyStr> twosBucket;
auto ostriter = std::ostream_iterator<MyStr>(std::cout, ",");
std::for_each(testVec.begin(), testVec.end(),
[&](const MyStr& next){
switch (next.key) {
case 4:
foursBucket.push_back(next);
break;
case 3:
threesBucket.push_back(next);
break;
case 2:
twosBucket.push_back(next);
break;
}
});
std::cout << "Elements with Key Value 2" << std::endl;
std::copy(twosBucket.begin(), twosBucket.end(), ostriter);
std::cout << std::endl;
std::cout << "Elements with Key Value 3" << std::endl;
std::copy(threesBucket.begin(), threesBucket.end(), ostriter);
std::cout << std::endl;
std::cout << "Elements with Key Value 4" << std::endl;
std::copy(foursBucket.begin(), foursBucket.end(), ostriter);
std::cout << std::endl;
}
产生以下输出
Elements with Key Value 2
key[2], strval['key 2'],key[2], strval['key 2'],key[2], strval['key 2'],
Elements with Key Value 3
key[3], strval['key 3'],key[3], strval['key 3'],
Elements with Key Value 4
key[4], strval['key 4'],
如您所见,结构非常简单,我已经展示了当前如何使用谓词对对象进行排序,但我不知道从众多算法中选择哪种来有效地迭代
【问题讨论】:
-
您可能只是在寻找类似
std::multiset的东西吗?它将是一个容器,存储不会是连续的,但是如果您可以简单地存储迭代器范围,我不明白您需要不同的容器来做什么。 -
我需要能够分别处理这些单独的范围中的每一个——这就是我有单独的桶的原因。理想情况下,如果我可以调用一些以输入范围作为参数的魔术谓词 -r lambda 函数,我就完成了,谓词将被调用的次数与唯一键的次数一样多
标签: c++ algorithm sorting c++11 stl