C++多集与结构只擦除一个,快速(过载?
C++ multiset with struct erase only one, fast (overload?)
struct node {
int idx; // each node have a unique index
int value; // different nodes can have same value
}
struct node_help {
bool operator()(const node &a, const node &b) const
{
return a.value < b.value;
}
}
std::multiset<node, node_help> Nodes;
目前为止,一切都好。现在我想从多集中擦除特定节点。当我使用它时:
Nodes.erase(node (x, y));
每个值为 y 的节点都会被删除,但我只希望删除值为 y 和索引 x 的节点。
我通过手动执行此操作解决了这个问题:
for (std::multiset<node, node_comp>::iterator iter = Nodes.begin(); iter != Nodes.end(); iter++) {
node actual_node = *iter;
if (actual_node.idx == to_delete.idx && actual_node.value == to_delete.value) {
Nodes.erase(iter);
}
return;
}
但这似乎表现不佳。我有数百万个节点,我需要我能得到的每一个加速。:)有什么想法吗?
好吧,一切都很好。我只是忘了在注销时取下线路。因此,在每次更改集后,都会创建一个日志并将其直接保存到磁盘中。注释掉这一点将时间从 50 秒减少到 0,0x 秒。足够快。:)但无论如何,所有的回应都是如此。
struct node_help {
bool operator()(const node &a, const node &b) const
{
return a.value <= b.value; // changes the equality check
}
}
如果您有 C++11,您可以按如下方式定义 lambda 并使其成为更好的代码。否则,您可能需要使用函数对象来代替 lambda。
std::remove(std::begin(Nodes), std::end(Nodes),
[&to_delete]( struct node & x )
{
return ( x.idx == to_delete.idx &&
x.value == to_delete.value);
}
请注意,要使用 std::remove(),您必须包含算法头文件:
#include<algorithm>
您可以以某种方式获得等于 node (x, y)
的元素的迭代器。然后,使用迭代器擦除将仅删除一个元素。
也就是说,使用这样的比较功能,无论如何您都会遇到一些麻烦(就复杂性而言)找到node (x, y)
,因为具有相同y
和不同x
的节点无法通过x
有效地搜索。
一种解决方案是将比较函数更改为按y
排序,然后按x
排序,并且可能使用集合而不是多重集合。之后,如果你想要一个具有特定y
的元素,你可以使用类似 Nodes.lower_bound (node (-INFINITY, y))
的东西,它具有复杂性 O(log n)。
how about
std::multiset<node, node_help> Nodes;
Nodes.insert(node{ 1, 10 });
Nodes.insert(node{ 2, 1 });
Nodes.insert(node{ 3, 1 });
Nodes.insert(node{ 4, 100 });
cout << "beforen";
for (const auto& n : Nodes)
{
cout << n.idx << " " << n.value << "n";
}
auto it = Nodes.find(node{ 0,1 });
while(it != Nodes.end())
{
Nodes.erase(it);
it = Nodes.find(node{ 0,1 });
}
cout << "naftern";
for (const auto& n : Nodes)
{
cout << n.idx << " " << n.value << "n";
}
您可以通过仅查看y
匹配的节点来获得恒定因子加速
auto [first, last] = Nodes.equal_range(to_delete);
auto it = std::find(first, last, to_delete);
if (it != last) {
Nodes.erase(it);
}
或者没有C++17
auto range = Nodes.equal_range(to_delete);
auto it = std::find(range.first, range.second, to_delete);
if (it != range.second) {
Nodes.erase(it);
}
使用 C++14,您可以按node
或int
搜索节点
struct node {
int idx; // each node have a unique index
int value; // different nodes can have same value
};
struct node_less {
using is_transparent = void;
bool operator()(const node &a, const node &b) const
{
return std::tie(a.value, a.key) < std::tie(b.value, b.key);
}
bool operator()(int a, const node &b) const
{
return a < b.value;
}
bool operator()(const node &a, int b) const
{
return a.value < b;
}
};
std::set<node, node_less> Nodes;
Nodes.find(node{ x, y }); // single node
Nodes.equal_range(y); // all nodes that match y
相关文章:
- 为什么这个快速排序实现给出了一个奇怪的输出
- 在矢量中使用擦除时双重释放或损坏(快速顶部).如何擦除一个矢量的几个项目知道它们的索引?
- 创建一个结构的关联数组,以创建一个缓冲区,供键快速访问
- 找到所有与自己求和的数字X的快速方法,去掉一个数字得到N
- 我想要一个改变数组快速排序的2个数字的函数
- C++: free(): 无效的下一个大小(快速)
- C++一个具有 2 个参数(___ _____,整数长度)的函数中的快速排序
- free():多次调用后下一个大小(快速)无效
- 快速从文件中读取下一个字符串,而无需移动文件的位置
- 我写了一个快速的排序代码,逻辑似乎很正确,但是控制台上没有输出
- 快速简单的方法,以C++为单位一次读取一个字节的 stdin
- 从C 库中制作一个快速共享的框架
- 我正在写一个快速的形式,可以跟踪迭代次数.但是,计数每次返回0.我怎样才能解决这个问题
- 将矢量<int>推入矢量<矢量<int>>时,SIGABRT - free():下一个大小无效(快速)
- 我刚刚创建了一个非常快速的素数排序方法.如何改进?
- free(): 无效的下一个大小 (快速): 0x0000000000f45160 ***.
- 我怎样才能写出一个快速函数来计算一个数的除数
- 是否有一个快速的内存中队列,我可以使用它在达到一定大小时交换项目
- 一个快速的new/delete和alloc/free
- 编译一个快速修复程序