我有一个关于std :: set容器的简短问题.现在我正在使用pushback功能来提供我的设置.对于每个push_back,该集合变得越来越大.我只对最新的30个元素感兴趣......可以删除旧元素.所以我的想法是将集合的大小限制为30个元素左右,并通过这样做摆脱不需要的旧元素.但是,默认情况下,该集不支持限制.我可以偶尔检查一下这个集的大小,然后手动删除多余的元素.有更聪明的方法吗?
关心Lumpi
有没有一种简单的方法来检测何时没有发生插入插入,因为插入的项目已经存在于集合中?例如,我想向用户显示一条消息,显示插入失败,以便他们可以更轻松地查找和删除其数据中的重复项.这里有一些伪代码来演示我想要做的事情:
try
{
items.insert(item)
}
catch insert_failed_item_already_in_set
{
// show user the failed item
}
Run Code Online (Sandbox Code Playgroud) 我有一个枚举,我想把它们全部放在集合中(然后使用set_intersection算法删除一些,但这是offtopic).一切都很好,除了我坚持第1步.:)
如果我有(真正的班级有更高的基数枚举)
class MyClass
{
enum Color{red, green , blue}
};
Run Code Online (Sandbox Code Playgroud)
我如何初始化std::set<MyClass::Color> 包含所有枚举.
我显然可以逐个手动插入它们,使用连接执行for循环,因为它们是连续的并且从0开始(我认为如果我不在枚举定义中使用=,则需要这样做),但我正在寻找更优雅的方式.
编辑:如果可能的话,我更喜欢C++ 03解决方案,因为当前的问题实例需要它,但如果不是,C++ 11也很好.
我有一个std::set存储std::pair两个整数的s.该std::set还排序,允许我通过一个帮扶类.但是,到目前为止,我已经编写了许多代码行,现在,在最后的测试中,"他们"告诉了我一些事实,这实际上意味着我需要允许重复std::set.当然,这不是完成的std::set.任何不会让我改变整个大项目的替代方案?
简而言之,我使用std::set带有std::pair两个整数的数据的有序列表.
我有一个元素的向量.我想使用匹配特定条件的此向量元素填充集合.我可以使用一行,或以比下面更简洁的方式执行此操作吗?
// given vector<int> v
set<int> s;
for (const int& i : v)
{
if (/* some condition on i*/)
s.insert(i);
}
Run Code Online (Sandbox Code Playgroud)
例如,以下内容:
// given vector<int> v
set<int> s;
s.insert(v.filter(/* lambda here*/));
Run Code Online (Sandbox Code Playgroud)
不言而喻,出于性能原因,v.filter方法应返回迭代器,而不是单独的填充向量.
考虑以下.
我有两个std::sets,并希望std::vector按排序顺序合并它们.
哪种方法最有效?
我做了类似的事情,但我认为必须有更好的方法.
std::set<int> S1;
std::set<int> S2;
// ....
// Initialization of sets
// ....
std::vector V;
std::set<int>::iterator iter;
for(iter = S1.begin(); iter!=S1.end(); ++iter)
{
V.push_back(*iter);
}
for(iter = S2.begin(); iter!=S2.end(); ++iter)
{
V.push_back(*iter);
}
std::sort(V.begin(), V.end());
Run Code Online (Sandbox Code Playgroud)
这是我的代码,有更有效的方法吗?提前致谢.
我可以做的一件事是分配一个大小为n的向量并存储所有数据,然后使用sort(begin(),end())对其进行排序.另外,我可以继续将数据放在一个地图中或设置自己订购的数据,这样我就不用事了.但在这种情况下,由于重新排列(我猜),插入元素可能会更昂贵.
因此,对于大范围的n(对象的数量)来说,这是最短时间的最佳选择
我试图优雅地声明一个常量std::set对象,它将是另外两个常量std::set对象的合并。
#include <set>
const std::set<int> set_one = { 1,2,3 };
const std::set<int> set_two = { 11,15 };
const std::set<int> set_all = { 1,2,3,11,15 }; // this is not very elegant, duplication
Run Code Online (Sandbox Code Playgroud)
以set_all这种方式声明对象不太优雅,因为它复制了前两行的信息。有没有办法在声明中使用set_one和set_two常量set_all?
像这样的东西:
const std::set<int> set_all = set_one + set_two; // this does not compile, of course!
Run Code Online (Sandbox Code Playgroud)
#include <set>
#define SET_ONE 1, 2, 3
#define SET_TWO 11, 15
const std::set<int> set_one = { SET_ONE …Run Code Online (Sandbox Code Playgroud) 我意外地发现插入排序的键std::set比插入混洗的键要快得多。这有点违反直觉,因为一棵红黑树(我证实std::set作为自平衡二叉搜索树在我的系统上是作为红黑树实现的)需要做很多重新平衡操作来插入排序的序列键,因此插入排序的键应该比插入混洗的键花费更多的时间。
但事实是,插入排序的键比插入混洗的键快 15 倍!这是我的测试代码和一些结果:
#include <algorithm>
#include <chrono>
#include <iostream>
#include <random>
#include <set>
#include <vector>
using namespace std;
int64_t insertion_time(const vector<int> &keys) {
auto start = chrono::system_clock::now();
set<int>(keys.begin(), keys.end());
auto stop = chrono::system_clock::now();
auto elapsed = chrono::duration_cast<chrono::milliseconds>(stop - start);
return elapsed.count();
}
int main() {
size_t test_size;
cout << "test size: ";
cin >> test_size;
vector<int> keys(test_size);
for (int i = 0; i < test_size; ++i) {
keys[i] = i;
}
// whether shuffled case …Run Code Online (Sandbox Code Playgroud) 示例代码:
#include <string>
#include <set>
using namespace std;
class x
{
private:
int i;
public:
int get_i() const { return i; }
};
struct x_cmp
{
bool operator()(x const & m1, x const & m2)
#if _MSC_VER
const
#endif
{
return m1.get_i() > m2.get_i();
}
};
std::set<x, x_cmp> members;
void add_member(x const & member)
{
members.insert(member);
}
Run Code Online (Sandbox Code Playgroud)
调用:
$ g++ -c -std=c++14 -pedantic -Wall -Wextra
<nothing>
$ clang++ -c -std=c++14 -pedantic -Wall -Wextra
<nothing>
$ icc -c -std=c++14 -pedantic -Wall …Run Code Online (Sandbox Code Playgroud)