C++ 类类型集
您是否可以编写一个重载函数来从设置中删除数据对象,例如:C++ 类类型集,c++,stl,C++,Stl,您是否可以编写一个重载函数来从设置中删除数据对象,例如:s.erase(4)Here4可以是值或x或y struct DATA { DATA(int X, int Y):x(X), y(Y){} int x; int y; bool operator < (const DATA &d) const { return x < d.x || (x == d.x && y < d.y); } }; int
s.erase(4)
Here4
可以是值或x或y
struct DATA
{
DATA(int X, int Y):x(X), y(Y){}
int x;
int y;
bool operator < (const DATA &d) const
{
return x < d.x || (x == d.x && y < d.y);
}
};
int main()
{
set <DATA> s;
for (int i = 0; i < 5; i++)
s.insert(DATA(i, i+5));
s.erase(0) // remove where x = 0
}
struct数据
{
数据(intx,inty):X(X),Y(Y){
int x;
int-y;
布尔运算符<(常数数据和d)常数
{
返回x
否;您的集合是按X排序的,您也不能按Y排序集合以便按其删除。您需要遍历集合以查找要删除的项目,然后像通常从集合中删除一样删除它们。否;您的集合是按X排序的,您也不能按Y排序集合以便按其删除。您需要遍历集合以查找要删除的项目,然后像通常从集合中删除一样删除它们。当然
您可以编写一个函子来搜索x或y为4的集合元素,并删除这些元素。您需要boost::bind
使绑定更容易:
#include <set>
#include <algorithm>
#include <boost/bind.hpp>
struct Foo {
int x, y;
bool operator<(const Foo& rhs) const {
return (x < rhs.x || (x == rhs.x && y < rhs.y));
}
bool hasValue(int v) const {
return (x == v || y == v);
}
};
int main()
{
std::set<Foo> s;
Foo a = {4,2}; s.insert(a);
Foo b = {3,4}; s.insert(b);
std::cout << s.size() << std::endl; // will output: "2"
std::set<Foo>::iterator it;
// Search for an element with the given value '4' in either x or y
// Erase first matching element found, if any
// (our first element, which has x=4)
it = std::find_if(s.begin(), s.end(), boost::bind(&Foo::hasValue, _1, 4));
if (it != s.end())
s.erase(it);
std::cout << s.size() << std::endl; // will output: "1"
// Erase the next one
// (our second element, which has y=4)
it = std::find_if(s.begin(), s.end(), boost::bind(&Foo::hasValue, _1, 4));
if (it != s.end())
s.erase(it);
std::cout << s.size() << std::endl; // will output: "0"
}
#包括
#包括
#包括
结构Foo{
int x,y;
布尔运算符当然
您可以编写一个函子来搜索x或y为4的集合元素,并删除这些元素。您需要boost::bind
使绑定更容易:
#include <set>
#include <algorithm>
#include <boost/bind.hpp>
struct Foo {
int x, y;
bool operator<(const Foo& rhs) const {
return (x < rhs.x || (x == rhs.x && y < rhs.y));
}
bool hasValue(int v) const {
return (x == v || y == v);
}
};
int main()
{
std::set<Foo> s;
Foo a = {4,2}; s.insert(a);
Foo b = {3,4}; s.insert(b);
std::cout << s.size() << std::endl; // will output: "2"
std::set<Foo>::iterator it;
// Search for an element with the given value '4' in either x or y
// Erase first matching element found, if any
// (our first element, which has x=4)
it = std::find_if(s.begin(), s.end(), boost::bind(&Foo::hasValue, _1, 4));
if (it != s.end())
s.erase(it);
std::cout << s.size() << std::endl; // will output: "1"
// Erase the next one
// (our second element, which has y=4)
it = std::find_if(s.begin(), s.end(), boost::bind(&Foo::hasValue, _1, 4));
if (it != s.end())
s.erase(it);
std::cout << s.size() << std::endl; // will output: "0"
}
#包括
#包括
#包括
结构Foo{
int x,y;
布尔运算符使用
这里有一个。用法
这里是一个。当然-您可以修改数据结构以操作较大的整数类型,并使用位移位将一对较小的整数类型打包到中。但是,在更一般的意义上,则不是。有些容器是多索引的,但std::set不是其中之一。当然-您可以修改数据结构以操作较小的整数类型更大的整数类型,并使用位移位将一对较小的整数类型打包。但是,在更一般的意义上,则不是。有多个索引的容器,但std::set不是其中之一。关于std::map
容器如何?您可以使用x或y作为键类型,并将类中的非键值保留为值类型.关于std::map
容器如何?您可以使用x或y作为键类型,并将类中的非键值保留为值类型。您不能简单地重载“操作符==”?您不能简单地重载“操作符==”?不,他的集合是按x
和y
排序的。请查看他的比较器函数。(事实上,“问题”是指他不能有选择地对其中一个进行索引;它们作为一对值紧密相连。)@Tomalak:y是一个辅助键——该集合由x索引,y用于断开联系。你可以查找主键(x),但不能查找辅助键(至少,不能使用单个集合结构)。他将如何使用std::set
的机制来查找x
?容器的密钥几乎等同于std::pair
,而不是int
@Tomalak:Find Data(WantedXValue,0)和Data(WantedXValue+1,0)(这将为您提供具有该x值的项目范围)在lg n
时间中。不,他的集合是按x
和y
排序的。请参见他的比较器函数。(事实上,“问题”在于他无法选择性地对其中一个进行索引;它们作为一对值紧密相连。)@Tomalak:y是一个辅助键——集合由x索引,y用于断开连接。您可以查找主键(x),但不能按辅助键查找(至少不能使用单个集合结构)。他将如何使用std::set
的机制来查找x
?容器的密钥几乎等同于std::pair
,而不是int
@Tomalak:Find Data(WantedXValue,0)和Data(WantedXValue+1,0)(这将为您提供具有该x值的项目范围)在lg n
time中。是的,你可以对整个过程进行迭代,但你无法获得集合的性能特征(你的搜索和删除需要O(n^2 lg n)时间,而你希望一个集合需要O(lg n)时间)。更好的是,使用一个手写循环,标记你想要删除的所有元素,然后一次性删除它们(如我的回答所示)将总时间降至O(n lg n)。至于失去集合的性能特征,这是OP的固有要求。老实说,在我看来,想要做到这一点首先有点代码味道。我建议在这里使用std::multimap
。比利,你怎么看?@Tomalak:multimap每个键存储多个项目,而不是多个键per项。@Billy ONeal:对不起,实际上想到的是boost::bimap
。他想要映射行为,他想在任意一个方向上建立索引。是的,你可以迭代整个过程,但你得不到集合的性能特征(你的搜索和删除需要O(n^2 lg n)时间,而一个集合需要O(lg n)时间)。更好的方法是,使用手写循环标记所有要删除的元素,并一次性删除它们(如我的答案所示),这会将总时间降低到O(n lg n)。至于失去集合的性能特征,这是OP的固有要求。老实说,在我看来,想要做到这一点首先有点代码味道。我建议在这里使用std::multimap
。比利,你怎么看?@Tomalak:multimap每个键存储多个项目,而不是多个键per项。@Billy ONeal:对不起,实际上想到的是boost::bimap
。他想要映射行为,他想在任意方向上建立索引。我不确定合并到一个更大的整数类型将如何帮助搜索std::set中的部分值。无论如何,即使这是可能的,我认为你也不应该给初学者关于h的想法如何混淆他们的代码以使其被遗忘…:)我不是真正的s