按字母顺序按两个标准对向量内的结构进行排序

Sorting structures inside vector by two criteria in alphabetical order

我有以下数据结构(第一个字符串作为学校的“主题”)

map<string, vector<School>> information;

学校是:

struct School {
   string name;
   string location;
}

我无法按字母顺序打印出我的整个数据结构(第一个主题,然后是位置,然后是名称)。举个例子。

"map key string : struct location : struct name"
"technology : berlin : university_of_berlin"

到目前为止,我设法通过

遍历了初始地图
for (auto const key:information) {
   //access to struct
   vector<School> v = key.second;
   //sorting by location name
   //comparasion done by seperate function that returns school.location1 < school.location2
   sort(v.begin(), v.end(), compare);

如果我打印出主题 (key.first) 和 v.location,它就差不多完成了。地图默认排序,位置比较有效。但我不知道如何按名称添加第二个比较。如果我再做一次排序,这次是按名称排序,那么我将丢失按位置排序的原始顺序。是否有可能在一个标准比另一个标准更重要的情况下进行“双重排序”?

可以,你只需要在compare

中添加一些条件
bool compare(School const& lhs, School const& rhs)
{
    if(lhs.location != rhs.location)
        return lhs.location < rhs.location)
    return lhs.name < rhs.name
}

或者您可以重载 < 运算符,就像@ceorron 那样

对此有一个简单的答案,我假设您想先按 "location" 然后 "name"

订购

简单的方法是在struct School结构中实现一个less运算符。

示例代码:

//in School.hpp
struct School {
   string name;
   string location;
   bool operator<(const School& rhs) const;
}

//in School.cpp
bool School::operator<(const School& rhs) const {
    if(this->location < rhs.location)
        return true;
    if(rhs.location < this->location)
        return false;
    if(this->name < rhs.name)
        return true;
    if(rhs.name < this->name)
        return false;
    return false;
}

虽然还有其他方法,您现在可以像这样调用排序。

sort(v.begin(), v.end());

我添加这个答案只是为了迂腐。请参阅 以了解此特定情况的正确内容(我会说在大多数正常情况下)。

完全可以执行多次排序。诀窍是对每个额外的传递使用 stable 排序方法。 (稳定排序保留等效元素的相对顺序。)

默认的 std::sort 算法是 Introsort — 这不是一种稳定的排序(它使用快速排序 + 插入排序,但如果快速排序需要更长的时间,则切换到堆排序)。

方便的是,标准库为我们提供了 std::stable_sort 算法,供我们在需要稳定排序时使用。

稳定排序通常比不稳定排序慢,这就是为什么我们倾向于尽可能选择不稳定排序。第一遍您可以使用不稳定排序,但您必须对所有其他遍使用稳定排序。

std::sort       ( xs.begin(), xs.end(), compare_names     );  // 1st pass: secondary criterion
std::stable_sort( xs.begin(), xs.end(), compare_locations );  // 2nd pass: primary criterion

最终顺序将主要按位置排序,其次按名称排序。

您可以根据需要添加任意数量的排序路径。请记住,您按照重要性的相反顺序应用通行证。例如,如果您想按(姓氏、名字、年龄)对人员进行排序,则必须按相反的顺序应用排序:年龄、名字、姓氏。