此问题已在此处有答案:
How can I sort two vectors in the same way, with criteria that uses only one of the vectors?(9个回答)
9年前关闭。
这可能是最好的陈述作为一个例子。我有两个向量/列表:
People = {Anne, Bob, Charlie, Douglas}
Ages = {23, 28, 25, 21}
我想使用类似sort(People.begin(), People.end(), CustomComparator)
的东西根据年龄对People进行排序,但我不知道如何编写CustomComparator
来查看Ages而不是People。
6条答案
按热度按时间0tdrvxhp1#
明显的方法
通常的处理方法不是创建两个单独的向量/列表,而是创建一个包含名称和年龄的对象的向量/列表:
要获得基于年龄的排序,请传递一个查看年龄的比较器:
在旧的C++(C++11之前,所以没有lambda表达式)中,可以将比较定义为
operator<
的成员重载,或者定义为函数对象(重载operator()
的对象)来进行比较:然后你的排序看起来像这样:
至于是为类定义
operator<
,还是像我上面展示的那样使用一个单独的比较器对象,这主要是一个问题,即是否有一个对这个类“明显”的单一顺序。在我看来,按年龄对人进行分类并不一定是显而易见的。然而,如果在你的程序上下文中,很明显,除非你明确指定,否则将按年龄对人进行排序,那么将比较实现为
person::operator<
而不是在一个单独的比较类中实现比较是有意义的。其他方法
尽管如此,在一些情况下,在排序之前将数据合并到结构中确实是不切实际或不可取的。
如果是这样的话,你有几个选择要考虑。如果因为你使用的键太昂贵而无法交换(或者根本不能交换,尽管这很少见),所以普通的排序是不切实际的,你可以使用一种类型,在这种类型中,你存储要排序的数据沿着与每个键相关联的键集合的索引:
你也可以很容易地创建一个单独的索引,按照键的顺序排序,然后使用该索引来读取相关的值:
但是,请注意,在本例中,我们根本没有对项目本身进行排序。我们刚刚根据年龄对索引进行了排序,然后使用索引索引到我们想要排序的数据数组中--但是年龄和姓名都保持原来的顺序。
当然,在理论上,你可能会遇到这样一种奇怪的情况,上面的方法都不起作用,你需要重新实现排序来做你真正想要的事情。虽然我认为这种可能性是存在的,但我还没有在实践中看到过(我甚至不记得看到过一次我几乎决定这样做是正确的)。
vuv7lop32#
正如其他人所指出的,您应该考虑对People和Ages进行分组。
如果你不能/不想这样做,你可以为它们创建一个“索引”,并对该索引进行排序。例如:
现在,第n个人的名字是
people[pos[n]]
,年龄是ages[pos[n]]
lndjwyie3#
一般来说,你不会把你想保存在不同容器中的数据放在一起。为Person创建一个struct/class并重载
operator<
。或者这是一个可以扔掉的东西:
std::pair
已经实现了比较运算符。hfsqlsce4#
将它们保存在两个单独的数据结构中是没有意义的:如果重新排序
People
,就不再有到Ages
合理Map。qojgxg4l5#
我建议将这两个列表合并为一个结构列表。这样你就可以像dirkgently说的那样简单地定义
operator <
。wfveoks06#
“杰瑞·科芬”的回答非常明确和正确。
A只是有一个相关的问题,可能会给予一个很好的讨论的主题...:)
我不得不< T >根据向量的排序(假设sequence)重新排序矩阵对象(假设TMatrix)的列...TMatrix < T >类不提供对其行的引用访问(因此我不能创建一个结构来重新排序...),但方便地提供了一个方法TMatrix< T >::swap(row 1,row 2)...
这就是代码:
我相信这仍然是O(n log n)因为每一行不到位将交换一次。
玩得开心!:)