这可能是最好的例子.我有两个向量/列表:
People = {Anne, Bob, Charlie, Douglas}
Ages = {23, 28, 25, 21}
Run Code Online (Sandbox Code Playgroud)
我想根据他们的年龄使用类似的东西来对人们进行排序sort(People.begin(), People.end(), CustomComparator)
,但我不知道如何编写CustomComparator
以查看Ages而不是People.
Jer*_*fin 27
处理此问题的常用方法是创建一个包含名称和年龄的单个向量/对象列表,而不是创建两个单独的向量/列表:
struct person {
std::string name;
int age;
};
Run Code Online (Sandbox Code Playgroud)
要根据年龄进行排序,请通过一个查看年龄的比较器:
std::sort(people.begin(), people.end(),
[](auto const &a, auto const &b) { return a.age < b.age; });
Run Code Online (Sandbox Code Playgroud)
在较旧的C++(前C++ 11中,因此没有lambda表达式)中,您可以将比较定义为成员重载,operator<
或者将其作为函数对象(重载的对象operator()
)进行比较:
struct by_age {
bool operator()(person const &a, person const &b) const noexcept {
return a.age < b.age;
}
};
Run Code Online (Sandbox Code Playgroud)
然后你的排序看起来像:
std::vector<person> people;
// code to put data into people goes here.
std::sort(people.begin(), people.end(), by_age());
Run Code Online (Sandbox Code Playgroud)
至于在定义operator<
类之间进行选择,或者如上所示使用单独的比较器对象,主要是对于这个类是否存在"明显"的单个排序的问题.
在我看来,分类人总是按年龄排序并不一定显而易见.但是,如果在你的程序环境中,很明显除非你明确指出,否则按年龄对人进行排序,那么实现比较是有意义的,person::operator<
而不是像我一样在单独的比较类中在上面完成.
正如其他人所指出的那样,你应该考虑对人和年龄进行分组.
如果你不能/不想,你可以为它们创建一个"索引",然后对该索引进行排序.例如:
// Warning: Not tested
struct CompareAge : std::binary_function<size_t, size_t, bool>
{
CompareAge(const std::vector<unsigned int>& Ages)
: m_Ages(Ages)
{}
bool operator()(size_t Lhs, size_t Rhs)const
{
return m_Ages[Lhs] < m_Ages[Rhs];
}
const std::vector<unsigned int>& m_Ages;
};
std::vector<std::string> people = ...;
std::vector<unsigned int> ages = ...;
// Initialize a vector of indices
assert(people.size() == ages.size());
std::vector<size_t> pos(people.size());
for (size_t i = 0; i != pos.size(); ++i){
pos[i] = i;
}
// Sort the indices
std::sort(pos.begin(), pos.end(), CompareAge(ages));
Run Code Online (Sandbox Code Playgroud)
现在,第n个人的名字是people[pos[n]]
,它的年龄是ages[pos[n]]
归档时间: |
|
查看次数: |
23901 次 |
最近记录: |