使用索引排序,但保持索引顺序

std::sort using indices but maintaining index order

本文关键字:索引 顺序 排序      更新时间:2023-10-16

我有一个值向量。我想根据这些值得到一个排序的索引列表。

我已经得到这个工作相当好,除了相同的值发生。当出现相同的值时,我希望索引保持顺序。

例如,我有这个测试用例:

std::vector< size_t >   idx;
std::vector< int >      val;
for( int i = 0; i < 40; i++ )
{
    idx.push_back( i );
    val.push_back( i % 10 );
}
std::sort( idx.begin(), idx.end(), [&]( size_t a, size_t b )
    {
        return val[a] < val[b];
    } );

将索引数组排序为以下内容:

(0,10,30,20,1,31,21,11,2,22,12,32,3,13,23,33,4,14,24,34,5,15,25,35,6,16,26,36,7,17,27,37,8,28,18,38,9,29,19,39)

但是我希望数组的顺序是:

(0,10,20,30,1,11,21,31,2,12,22,32,3,13,23,33,4,14,24,34,5,15,25,35,6,16,26,36,7,17,27,37,8,18,28,38,9,19,29,39)

是否有一种简单的方法,我可以修改我的lambda来获得这些值在最后指定的顺序?

提前干杯!

您应该使用std::stable_sort。

在您的具体情况下,您可以调整lambda以在val[a] == val[b]时比较ab,但这会使您的意图对任何将来可能偶然发现此代码的未来开发人员变得模糊。

当val[a] == val[b]时,返回两个索引中较小的一个

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> val;
int compare(int a,int b)
{
    if(val[a] == val[b]) {
        return a < b;
    }
    return val[a] < val[b];
}
int main()
{
    vector<int> idx;
    int i;
    for(i = 0; i < 40; i++) {
        idx.push_back(i);
        val.push_back(i%10);
    }
    sort(idx.begin(),idx.end(),compare);
    for(i = 0; i < 40; i++) {
        cout<<idx[i]<<' ';
    }
}