【问题标题】:How do you perform a secondary sort while maintaining a primary sort如何在保持主要排序的同时执行次要排序
【发布时间】:2015-04-03 00:05:09
【问题描述】:

例如,我正在编写一个带有条目(字符串键、int 计数)的哈希表。首先,我进行选择排序以按计数对每个条目进行排序。然后我想在保持排序计数的同时按字母顺序对它们进行排序。有没有办法做到这一点?

这是主要排序。

void MyTrends::sortByCount(Entry* arr, int sizeOfArray) {
  int maxIndex; // the index of the element that has the highest count
  for(int i=0; i < sizeOfArray-1; i++){
      maxIndex = i;
      for(int j=i+1; j < m; j++){
          if(arr[j].getCount() > arr[maxIndex].getCount()){ //if the count of element j is higher than the count of the Entry at the current max index then change the max index to j
              maxIndex = j;
          }
      }
      if (maxIndex != i) {
          Entry temp = arr[i]; //next 2 lines + this line are swapping max to first position and old first position to the position the max was in
          arr[i] = arr[maxIndex];
          arr[maxIndex] = temp;
      }
  }
}

编辑:再想一想,这是否可以通过首先按字母顺序排序,然后使用稳定排序按计数排序来完成?

【问题讨论】:

  • 你是对的,如果你首先对辅助键进行排序,然后在稳定的排序算法中使用主排序键,它应该会给你想要的结果:)
  • 你的意思是当我们有两个字母顺序相同的元素时,计数最少的那个应该更小?
  • 与你刚才所说的相反。如果您有两个计数相同的键,我希望首先显示按字母顺序排列的第一个键。
  • @Slizzered 他是对的,但这仍然不是这样做的方法。这一切都可以在一个排序中完成。
  • 啊,下面的最佳答案是一种更好的方法。谢谢大家!

标签: c++ sorting selection


【解决方案1】:

您需要一个自定义的Entry 比较运算符。例如

struct Entry {
    int num;
    char letter;
}

bool operator< (const Entry& lhs, const Entry& rhs)
{
    if ( lhs.num == rhs.num )
        return lhs.letter < rhs.letter;
    else
        return lhs.num < rhs.num;
}

然后使用自定义比较对其进行排序。该列表将首先按数字(num 成员)排序,然后使用letter 成员按字母顺序排序。

【讨论】:

  • 谢谢。这比排序两次更有效!
  • 看看用 std::tuple 实现字典排序
【解决方案2】:
struct Entry {
  int num;
  char letter;
  friend auto make_tie(Entry const&e){
    return std::tie(e.num,e.letter);
  }
  friend bool operator<(Entry const&lhs, Entry const& rhs){
    return make_tie(lhs)<make_tie(rhs);
  }
};

这会利用tuple 的字典排序来对您的条目进行排序。 tie 创建一个引用元组。

它需要写make_tie,但是一旦你有了它,你就可以免费获得==&lt;,你也可以将它用于其他一些功能——序列化、打印、swap等。

make_tie 是 C++14 -- 对于 C++11,您需要在 )make_tie{ 之间添加一个 -&gt;decltype(std::tie(e.num,e.letter))

【讨论】:

  • 这正是我会做的,赞成!不知道为什么你想要一个额外的 make_tie,为什么不直接使用return std::tie(...) &lt; std::tie(...)
  • @vsoftco DRY:这需要成员列表的两个副本(并且一些订单错误不会被捕获!)。它也可以通过这种方式在==swap和其他方法中重复使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-01
  • 2020-12-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多