C++中如何在集合中查找
how to search in a set in c++
我有一套 class 件:
std::set <Item> items;
class Item
{
private:
std::string name;
std::string serialNum;
int count;
double unitPrice;
public :
Item(std::string _name, std::string _serialNum, int _count, double _unitPrice);
Item(); // Ctor with no parameters , for compiling
~Item(); //Dtor
double totalPrice();
bool operator<(Item const & other)const;
bool operator>(Item& other);
bool operator==(Item& other);
void operator=(const Item& other);
void countUp();
void countDown();
void setup(std::string _name, std::string _serialNum, int _count, double _UnitPrice);
int getCount() const ;
std::string getName() const;
std::string getSerial() const ;
double getPrice() const ;
void printItem() const ;
};
我可以只按一个值在集合中搜索吗?
例如,在集合中搜索 item :: name .
Set description。
Set find, Set key comp。
创建集合时,您可以提供 Compare
class 用于比较元素。
根据规范:
A binary predicate that takes two arguments of the same type as the elements and returns a bool. The expression comp(a,b), where comp is an object of this type and a and b are key values, shall return true if a is considered to go before b in the strict weak ordering the function defines. (...) defaults to less, which returns the same as applying the less-than operator (a
默认情况下,set 使用 less<T>
比较元素,但您可以提供 class 以您定义的方式比较项目。
std::set
是有序的(通常使用 operator<
,你可以为你的类型重载)。通常,您决定 一个特定订单 。 (也许是你的 serialNum
?)
如果您使用不同的标准搜索同一组,例如name
在你的情况下,你需要一个元素一个元素地遍历整个集合,因为集合订单没有利润。
为此,有标准算法 std::find_if
,它在线性时间内完成:
std::string name_to_find = "foo bar";
auto it = std::find_if(items.begin(), items.end(),
[name_to_find](const Item & i){ return i.getName() == name_to_find; });
将为您提供一个迭代器 it
指向集合中名称为 name_to_find
的第一个项目(如果集合中不存在这样的元素,则为结束迭代器)。它独立于您提供的容器类型,因此它适用于集合、向量、数组...,并忽略容器的可能顺序。
以上代码使用 C++11 lambda 提供字面上内联的比较函数。如果你的编译器还不支持(或者如果你想支持旧的编译器),你必须使用仿函数来提供相同的功能。仿函数是一个 class,它的行为类似于一个函数(可以使用 operator()
调用)。
// Functor class to compare the name of an item with a specific name to look for
struct ItemByName {
// The functor needs to remember what we're looking for in a member variable
std::string name_to_find;
// Constructor initializing the name to look for
ItemByName(std::string name_to_find) : name_to_find(name_to_find) {}
// The call-operator which is called by the algorithm find_if
bool operator()(const Item &i) const {
// This is the same body as in the lambda
return i.getName() == name_to_find;
}
};
然后通过构造此仿函数的实例在 find_if
中使用它:
std::set<Item>::iterator it = std::find_if(items.begin(), items.end(),
ItemByName(name_to_find));
请注意,返回值现在被捕获在具有显式类型的变量中。在 C++11(以上)中,我们可以使用 auto
使其更易于键入。
我有一套 class 件:
std::set <Item> items;
class Item
{
private:
std::string name;
std::string serialNum;
int count;
double unitPrice;
public :
Item(std::string _name, std::string _serialNum, int _count, double _unitPrice);
Item(); // Ctor with no parameters , for compiling
~Item(); //Dtor
double totalPrice();
bool operator<(Item const & other)const;
bool operator>(Item& other);
bool operator==(Item& other);
void operator=(const Item& other);
void countUp();
void countDown();
void setup(std::string _name, std::string _serialNum, int _count, double _UnitPrice);
int getCount() const ;
std::string getName() const;
std::string getSerial() const ;
double getPrice() const ;
void printItem() const ;
};
我可以只按一个值在集合中搜索吗? 例如,在集合中搜索 item :: name .
Set description。
Set find, Set key comp。
创建集合时,您可以提供 Compare
class 用于比较元素。
根据规范:
A binary predicate that takes two arguments of the same type as the elements and returns a bool. The expression comp(a,b), where comp is an object of this type and a and b are key values, shall return true if a is considered to go before b in the strict weak ordering the function defines. (...) defaults to less, which returns the same as applying the less-than operator (a
默认情况下,set 使用 less<T>
比较元素,但您可以提供 class 以您定义的方式比较项目。
std::set
是有序的(通常使用 operator<
,你可以为你的类型重载)。通常,您决定 一个特定订单 。 (也许是你的 serialNum
?)
如果您使用不同的标准搜索同一组,例如name
在你的情况下,你需要一个元素一个元素地遍历整个集合,因为集合订单没有利润。
为此,有标准算法 std::find_if
,它在线性时间内完成:
std::string name_to_find = "foo bar";
auto it = std::find_if(items.begin(), items.end(),
[name_to_find](const Item & i){ return i.getName() == name_to_find; });
将为您提供一个迭代器 it
指向集合中名称为 name_to_find
的第一个项目(如果集合中不存在这样的元素,则为结束迭代器)。它独立于您提供的容器类型,因此它适用于集合、向量、数组...,并忽略容器的可能顺序。
以上代码使用 C++11 lambda 提供字面上内联的比较函数。如果你的编译器还不支持(或者如果你想支持旧的编译器),你必须使用仿函数来提供相同的功能。仿函数是一个 class,它的行为类似于一个函数(可以使用 operator()
调用)。
// Functor class to compare the name of an item with a specific name to look for
struct ItemByName {
// The functor needs to remember what we're looking for in a member variable
std::string name_to_find;
// Constructor initializing the name to look for
ItemByName(std::string name_to_find) : name_to_find(name_to_find) {}
// The call-operator which is called by the algorithm find_if
bool operator()(const Item &i) const {
// This is the same body as in the lambda
return i.getName() == name_to_find;
}
};
然后通过构造此仿函数的实例在 find_if
中使用它:
std::set<Item>::iterator it = std::find_if(items.begin(), items.end(),
ItemByName(name_to_find));
请注意,返回值现在被捕获在具有显式类型的变量中。在 C++11(以上)中,我们可以使用 auto
使其更易于键入。