在c++中对对象向量进行排序
Sorting a vector of objects in C++
假设我有一个类"Information",它将人们的姓名和年龄存储在一个向量中。
所以…
class Information {
private:
int age;
string name;
//etc, etc...
};
我如何根据年龄以升序/降序对向量进行排序?
我相信你用的是这样的东西。
sort(listOfPeople.begin(), listOfPeople.end(), greater<Information>());
listOfPeople将作为向量。
如果希望按年龄按非降序排序,一种方法是定义一个函子进行比较:
class CompareInformations {
public:
// after making CompareInformations a friend class to Information...
operator(const Information& rhs, const Information& lhs) {
return rhs.age < lhs.age;
}
};
然后排序:
sort(listOfPeople.begin(), listOfPeople.end(), CompareInformations());
您也可以为您的类重载operator<
,而不使用比较对象:
// inside your class
bool operator <(const Information& rhs) {
return age < rhs.age;
}
然后排序:
sort(listOfPeople.begin(), listOfPeople.end());
上面的示例假设您希望按非降序(几乎升序,但不完全是)顺序排序。要实现非升序,只需将出现的所有<
更改为>
。
您需要创建一个比较器函数或函子类,它接受两个Information
引用,如果第一个应该在第二个之前排序,则返回true
。
下面将从老到小排序:
bool CompareAges(const Information & left, const Information & right)
{
return left.age > right.age;
}
std::sort(listOfPeople.begin(), listOfPeople.end(), CompareAges);
选择是升序排序还是降序排序,您可以使用不同的比较函数对sort
进行两次不同的调用,或者您可以创建一个函数类,该函数类具有决定项如何排序的标志。
struct CompareAgesUpOrDown
{
CompareAgesUpOrDown(bool bDown) : m_bDown(bDown) {}
bool operator() (const Information & left, const Information & right)
{
if (m_bDown)
return left.age < right.age;
else
return left.age > right.age;
}
bool m_bDown;
};
bool bDown = ...;
std::sort(std::sort(listOfPeople.begin(), listOfPeople.end(), CompareAgesUpOrDown(bDown));
其他人已经展示了c++ 98/03的解决方案。在c++ 11中,您可能希望使用lambda进行比较:
// ascending age:
std::sort(people.begin(), people.end(),
[](person const &a, person const &b) { return a.age < b.age; });
// descending age:
std::sort(people.begin(), people.end(),
[](person const &a, person const &b) { return b.age < a.age; });
并且,如果它碰巧发生了:
// ascending name:
std::sort(people.begin(), people.end(),
[](person const &a, person const &b) { return a.name < b.name; });
// descending name:
std::sort(people.begin(), people.end(),
[](person const &a, person const &b) { return b.name < a.name; });
IMO, Information
是太通用的名字,所以我把它改成了person
。相反,listOfPeople
过于强调形式而不是内容(更糟糕的是,这是完全错误的,因为您实际上有一个人的向量,而不是一个列表)。在我看来,在编程中,通常最好只使用list
来引用链表,而不是一般的线性数据结构。
您需要有一个比较函数或对象才能使用该排序。请查看cplusplus.com上的排序页面以获取示例和信息。
下面是使用比较函数的完整示例:#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
class Information {
public:
Information(int age, std::string name) : m_age(age), m_name(name) {}
int age() const { return m_age; }
std::string name() const { return m_name; }
private:
int m_age;
std::string m_name;
friend bool sortInformationByAgeAscending(const Information& lhs,
const Information& rhs);
friend bool sortInformationByAgeDescending(const Information& lhs,
const Information& rhs);
};
bool sortInformationByAgeAscending(const Information& lhs,
const Information& rhs) {
return lhs.m_age < rhs.m_age;
}
bool sortInformationByAgeDescending(const Information& lhs,
const Information& rhs) {
return lhs.m_age > rhs.m_age;
}
int main (int argc, const char * argv[])
{
std::vector<Information> info;
info.push_back(Information(1, "Bill"));
info.push_back(Information(5, "Ann"));
info.push_back(Information(2, "Sue"));
std::sort(info.begin(), info.end(), sortInformationByAgeAscending);
std::cout << info.at(0).age() << ": " << info.at(0).name() << std::endl;
std::cout << info.at(1).age() << ": " << info.at(1).name() << std::endl;
std::cout << info.at(2).age() << ": " << info.at(2).name() << std::endl;
return 0;
}
我会重载operator <
,然后使用greater排序。更大本质上意味着rhs <lh。然后使用sort(listOfPeople.begin(), listOfPeople.end(), greater<Information>());
>
如果你决定添加operator<
,你的类将很好地与std::set
和std::map
中的键配合,除了允许排序。
class Information {
private:
int age;
string name;
friend bool operator< (Information const& lhs, Information const& rhs){
return lhs.age < rhs.age;
}
//etc, etc...
};
对于降序排序,必须重载>运算符而不是<然后像这样用更大的选项调用sort:sort(listOfPeople.begin(), listOfPeople.end(), greater<Information>());
xmlns:然后像这样用更大的选项调用sort="#unknown">然后像这样用更大的选项调用sort:CC_16>
- 计算排序向量的向量中唯一值的计数
- 查找两个排序向量中共有的元素
- 对的排序向量 (std::vector<pair<int, int>>) 按对的第一个元素搜索并更新第二个元素值
- 如何从C++的对的排序向量中获取有关给定值的相应对
- 对象接收堆栈溢出异常 c++ 的排序向量
- "x"的所有元素都存在于"y"(排序向量)中吗?
- 指向指针排序向量的指针向量的 C++ 向量
- 未排序向量上的lower_bound/upper_bound
- 智能指针的排序向量:神秘崩溃
- 按类型排序向量并按类型或派生类型搜索
- 如何在不使用标准算法的情况下在排序向量中添加 c 元素?
- C++排序向量<double>与在<Object>双成员变量上键控的向量
- 字符串指针的排序向量
- 具有前导数字的字符串的排序向量
- 保证重新排序向量
- 结构解释的C 排序向量
- 更新排序向量的一个条目
- 通过在排序向量上使用二叉搜索来定位未排序向量中的元素
- 排序向量上 std::find_if 和 std::bind2nd 的替代品
- 使用QuickSort算法以降序排序向量