【问题标题】:std::sort using indices but maintaining index orderstd::sort 使用索引但保持索引顺序
【发布时间】:2015-09-10 15:28:13
【问题描述】:

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

除了出现相同值的情况外,我已经很好地完成了这项工作。当出现相同的值时,我希望索引保持有序。

例如我有这个测试用例:

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 以按照最后一个指定的顺序获取这些值?

提前干杯!

【问题讨论】:

标签: c++ sorting stl


【解决方案1】:

您应该使用std::stable_sort

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

【讨论】:

    【解决方案2】:

    当 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]<<' ';
        }
    }
    

    【讨论】:

    • wtf 在那里干吗?
    • 它包括所有需要的头文件。因此,在这种情况下,我不必编写 #include 和 #include 。阅读更多stackoverflow.com/questions/25311011/…
    • 它包括许多不需要的文件。而且它不是标准的,所以我认为你应该在例子中避免它。
    • 是的,我知道,但是在竞争性编程中,包含所有头文件需要很多时间。
    • 滥用编译器/标准库实现的实现细节不是一个好主意,因为它 a) 在编译器之间不可移植,并且 b) 可能随时中断。只需包含标准标题,这并不难,但更安全。
    猜你喜欢
    • 1970-01-01
    • 2021-04-15
    • 2020-10-19
    • 1970-01-01
    • 2021-08-10
    • 2020-11-02
    • 1970-01-01
    • 1970-01-01
    • 2013-02-17
    相关资源
    最近更新 更多