C++使用多个元素对数据进行双重排序
C++ double sorting data with multiple elements
我有多个数据条目,其中包含以下信息:id编号名称1日期名称2
可以将其放入这样的结构中:
struct entry {
int id_number;
string name1;
int date;
string name2;
}
在我的数据中,我有很多这样的条目,我想排序。首先,我想根据名称1按字母顺序排序,然后按日期排序。然而,按日期排序是字母排序的子集,例如,如果我有两个名称相同的条目1,那么我想按日期对这些条目进行排序。此外,当我排序时,我希望条目的元素保持在一起,所以所有四个值都在一起。
我的问题如下:
1) 我应该使用什么类型的数据结构来保存这些数据,这样当我按四个元素中的任何一个进行排序时,我就可以将它们放在一起了?
2) 进行排序的最快方法是什么(就编写代码的时间而言)。理想情况下,我想在算法.h中使用类似排序的东西,因为它已经内置在中了
3) STL是否有一些内置的数据结构,可以有效地处理我所描述的双重排序?
您拥有的结构很好,只是您可能想添加operator<
的重载来进行比较。在这里,我正在进行"按名称,然后按日期进行比较"比较:
// Add this as a member function to `entry`.
bool operator<(entry const &other) const {
if (name1 < other.name1)
return true;
if (name1 > other.name1)
return false;
// otherwise name1 == other.name1
// so we now fall through to use the next comparator.
if (date < other.date)
return true;
return false;
}
[编辑:所需的被称为"严格弱排序"。如果你想详细了解这意味着什么,以及可能的替代方案,Dave Abrahams在C++Next上写了一篇相当详细的文章。
在上面的例子中,我们首先比较两者的name1字段。如果a<b
,那么我们立即返回true。否则,我们检查a>b
,如果是,则返回false。在这一点上,我们已经消除了a<b
和a>b
,所以我们确定了a==b
,在这种情况下,我们测试日期——如果a<b
,我们返回true。否则,我们返回false——要么是日期相等,要么是b>a
,这两者都意味着a<b
的测试为false。如果排序需要排序(并非双关语),那么它可以在交换参数的情况下再次调用函数。名字仍然是相等的,所以它仍然会归结为日期——如果我们得到假,那么日期是相等的。如果我们在交换的日期上是真的,那么从第二个日期开始的日期实际上更大。]
您在结构中定义的operator<
定义了默认情况下将使用的顺序。如果需要,您可以指定另一个排序顺序:
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());
那里的数据结构应该可以正常工作。您应该做的是覆盖小于运算符,然后您可以将它们全部插入到映射中,然后对它们进行排序。以下是关于地图的比较运算符的更多信息
更新:经过进一步思考,我会使用集合,而不是地图,因为不需要值。但这里有证据表明它仍然有效
证明这一点:
#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("%sn ", it->first.toString().c_str());
}
return 0;
}
实际上,您可以使用函数对象来实现您的排序标准
假设您想将条目存储在设置的中
//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
}
- 如何对点云数据进行排序
- 如何使用 QSortFilterProxyModel::sort 对 Qlist 中的数据进行排序
- 保持排序的数据结构,允许log N插入时间,并且可以返回我在log N中查找的元素的索引
- 使用选择排序对数组数据结构进行排序,但它不起作用
- 为什么我的代码没有对数组中第二个索引上的数据进行排序?
- 使用 QSortFilterProxyModel 对 Qml ListView 的数据进行排序
- 读取 C++ 中的 txt 数据,展开为行或列并排序
- C++ 从文件中获取数据时使用 strcpy 和 strcmp 按字母顺序对数组进行排序?
- 存储在 std::map/std::set 中,与在存储所有数据后对向量进行排序
- 尝试创建排序的动态列表(数据结构)
- 固定大小的容器,其中元素被排序,并可以为C 中的数据提供原始指针
- 排序算法,使用模板按内部数据对对象进行排序
- 对多个数据成员进行排序
- 递归定义数组中的数据对齐和排序
- 如何修复输出显示,以便显示正确排序的数据
- 是否有具有对数时间插入、删除和查找(带距离)的排序数据结构
- 为什么大多数STL算法都需要将排序数据作为输入
- 用于插入大部分排序数据的数据结构,这些数据将保持排序顺序
- 可更新的DAWG库或来自未排序数据的DAWG构造
- 实现在单链表中添加和排序数据的函数(addsort)