C++ C++;具有多个元素的双重排序数据

C++ C++;具有多个元素的双重排序数据,c++,sorting,data-structures,C++,Sorting,Data Structures,我有多个包含以下信息的数据项: 身份证号码 名称1 日期 姓名2 可以将其放入如下结构中: struct entry { int id_number; string name1; int date; string name2; } 在我的数据中,我有许多这样的条目,我想进行排序。首先,我想根据name1按字母顺序排序,然后按日期排序。但是,按日期排序是按字母顺序排序的子集,例如,如果我有两个名称相同的条目1,则我希望按日期对这些条目进行排序。此外,当我排序时,我希望条目的元素保

我有多个包含以下信息的数据项: 身份证号码 名称1 日期 姓名2

可以将其放入如下结构中:

struct entry {
  int id_number;
  string name1;
  int date;
  string name2;
}
在我的数据中,我有许多这样的条目,我想进行排序。首先,我想根据name1按字母顺序排序,然后按日期排序。但是,按日期排序是按字母顺序排序的子集,例如,如果我有两个名称相同的条目1,则我希望按日期对这些条目进行排序。此外,当我排序时,我希望条目的元素保持在一起,因此所有四个值都在一起

我的问题如下:

1) 我应该使用什么类型的数据结构来保存这些数据,以便在按四个元素中的任何一个进行排序时能够将四个元素的集合保存在一起

2) 进行排序的最快方法是什么(就编写代码的时间而言)。理想情况下,我想使用类似于sort in algorithms.h的东西,因为它已经内置了


3) STL是否有一些内置的数据结构可以有效地处理我描述的双重排序?

那里的数据结构应该可以正常工作。您应该做的是重写小于运算符,然后您可以将它们全部插入到一个映射中,并对它们进行排序

更新:进一步思考后,我会使用集合,而不是贴图,因为不需要值。但这里有证据证明它仍然有效

证明这是有效的:

#include<string>
#include<map>
#include<stdio.h>
#include <sstream>


using namespace std;

struct entry {
  int m_id_number;
  string m_name1;
  int m_date;
  string m_name2;

  entry(  int id_number, string name1, int date, string name2) :
      m_id_number(id_number),
      m_name1(name1),
      m_date(date),
      m_name2(name2)
  {

  }

  // Add this as a member function to `entry`.
  bool operator<(entry const &other) const {
      if (m_name1 < other.m_name1)
          return true;
      if (m_name2 < other.m_name2)
          return true;
      if (m_date < other.m_date)
          return true;
      return false;
  }

  string toString() const
  {
      string returnValue;

      stringstream out;
      string dateAsString;

      out << m_date;
      dateAsString = out.str();

      returnValue = m_name1 + " " + m_name2 + " " + dateAsString;

      return returnValue;
  }
};


int main(int argc, char *argv[])
{
    string names1[] = {"Dave", "John", "Mark", "Chris", "Todd"};
    string names2[] = {"A", "B", "C", "D", "E", "F", "G"};

    std::map<entry, int> mymap;
    for(int x = 0; x < 100; ++x)
    {
        mymap.insert(pair<entry, int>(entry(0, names1[x%5], x, names2[x%7]), 0));
    }

    std::map<entry, int>::iterator it = mymap.begin();
    for(; it != mymap.end() ;++it)
    {
        printf("%s\n ", it->first.toString().c_str());
    }
    return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
结构条目{
int m_id_编号;
字符串m_name1;
国际货币单位日期;
字符串m_name2;
条目(int id_编号、字符串名称1、int日期、字符串名称2):
m_id_编号(id_编号),
m_name1(name1),
m_日期(日期),
m_名称2(名称2)
{
}
//将此作为成员函数添加到“entry”。

bool操作符您拥有的结构很好,只是您可能需要添加一个重载
操作符,实际上您可以使用function对象来实现排序标准

假设您希望将条目存储在集合中

//EntrySortCriteria.h
class EntrySortCriteria
{
    bool operator(const entry &e1, const entry &e2) const
    {
         return e1.name1 < e2.name1 || 
                (!(e1.name1 < e2.name1) && e1.date < e2.date))
    }
}

//main.cc
#include <iostream>
#include "EntrySortCriteria.h"

using namespace std;
int main(int argc, char **argv)
{

    set<entry, EntrySortCriteria> entrySet;
    //then you can put entries into this set, 
    //they will be sorted automatically according to your criteria
    //syntax of set:
    //entrySet.insert(newEntry);
    //where newEntry is a object of your entry type    
}
//EntrySortCriteria.h
类入口标准
{
布尔运算符(常数输入和e1、常数输入和e2)常数
{
返回e1.name1
std::map不能保证是一个稳定的排序。我不是说进行多个排序。我是说进行一个排序,其中小于运算符权重的名称首先是名称,然后是日期。为什么一个排序时进行两个排序(稍微复杂一点)行吗?他需要一个稳定的排序,否则这就行不通了。我将放弃我自己的答案,因为它与您的答案非常相似,只是要说明std::stable_sort的速度非常慢,而另一个合并排序实现会好得多,因为最好和最坏的情况是n log n,而std::stable_sort类似于…n log n^2或其他什么那么,我会更新答案来解决这个问题。如果你这样做的话,我会投票支持你。或者我会在我自己的答案中解释这个理论…@OrgnlDave:不是这样。只有当你在两个字段上分别排序时,你才需要一个稳定的排序。也就是说,你先按日期排序,然后按名称分别排序,并希望日期保持顺序。这两种做法都是可行的Rison一次,因此单一排序(可能不稳定)按名称和日期排列。抱歉,该比较器无法提供稳定的sort@OrgnlDave:必要的是严格、弱的排序。您认为这不能提供这一点吗?讨论时,您可能需要阅读。仔细检查代码路径后,看起来应该可以这样做。解释一下为什么在我的书,但看起来不错。
struct byid { 
    bool operator<(entry const &a, entry const &b) { 
        return a.id_number < b.id_number;
    }
};

std::vector<entry> entries;

// sort by name, then date
std::sort(entries.begin(), entries.end());

// sort by ID
std::sort(entries.begin(), entries.end(), byid());
//EntrySortCriteria.h
class EntrySortCriteria
{
    bool operator(const entry &e1, const entry &e2) const
    {
         return e1.name1 < e2.name1 || 
                (!(e1.name1 < e2.name1) && e1.date < e2.date))
    }
}

//main.cc
#include <iostream>
#include "EntrySortCriteria.h"

using namespace std;
int main(int argc, char **argv)
{

    set<entry, EntrySortCriteria> entrySet;
    //then you can put entries into this set, 
    //they will be sorted automatically according to your criteria
    //syntax of set:
    //entrySet.insert(newEntry);
    //where newEntry is a object of your entry type    
}