【问题标题】:Sorting structures inside vector by two criteria in alphabetical order按字母顺序按两个标准对向量内的结构进行排序
【发布时间】:2021-12-12 18:28:05
【问题描述】:

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

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,就差不多完成了。地图默认排序,位置比较有效。但我不知道如何按名称添加第二个比较。如果我再次按名称进行排序,那么我会丢失按位置的原始顺序。是否有可能以某种方式“双重排序”,其中一个标准更重要,然后另一个?

【问题讨论】:

    标签: c++ sorting vector struct


    【解决方案1】:

    可以,只需要在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 那样重载 &lt; 运算符

    【讨论】:

    • 谢谢,这似乎解决了问题。虽然我颠倒了比较,因为这似乎给出了相反的字母顺序。
    【解决方案2】:

    对此有一个简单的答案,我假设您想先通过"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。

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

    【讨论】:

    • 由于未知的原因,这对我来说失败了,但无论如何感谢你关于运算符重载的课程。如果没有其他代码可能会干扰我的工作,我相信这也可以。
    【解决方案3】:

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

    完全可以执行多遍排序。诀窍是对每个额外的通道使用 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
    

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多