根据另一个向量对一个向量进行排序

Sort one vector according to another

我的问题基于这个问题的答案:

How to obtain the index permutation after the sorting

我有两个std::vectors:

std::vector<int> time={5, 16, 4, 7};   
std::vector<int> amplitude={10,17,8,16};

我想对向量进行排序以增加时间,所以最终它们将是:

TimeOrdered={4,5,7,16};
AmplitudeOrdered={8,10,16,17};

完成后,我想将两个有序向量添加到 CERN ROOT TTree。我在网上查找解决方案并找到上面的示例,其中最佳答案是使用以下代码:

vector<int> data = {5, 16, 4, 7};   
vector<int> index(data.size(), 0);
for (int i = 0 ; i != index.size() ; i++) {
    index[i] = i;
}
sort(index.begin(), index.end(),[&](const int& a, const int& b) {
                return (data[a] < data[b]);
              }
  );
for (int ii = 0 ; ii != index.size() ; ii++) {
  cout << index[ii] << endl;
}

我喜欢它,因为它很简单,不需要太多的行,它给我留下了两个简单的向量,然后我可以轻松地将其用于我的 TTree。

因此,我试图概括它:

  void TwoVectorSort(){

      std::vector<int> data={5, 16, 4, 7};   
      std::vector<int> data2={10,17,8,16};
      sort(data2.begin(), data2.end(),[&](const int& a, const int& b) {
                        return (data[a] < data[b]);
                      }
        );

      for (int ii = 0 ; ii != data2.size() ; ii++) {
        std::cout <<data[ii]<<"\t"<< data2[ii]<<"\t"<< std::endl;//<<index[ii] 
      }
}

但它不仅不起作用,而且每次都给我不同的东西。我 运行 它作为一个宏,ROOT 6.18/04,使用 .x TwoVectorSort.cpp+.

谁能告诉我为什么它不起作用以及最简单的解决方案是什么?我绝不是 C++ 专家,所以我希望答案不会太技术性!

提前致谢!

您确实可以重新使用您分享的 link 中的 solution 来解决您的问题。但是您需要继续构建 index 向量(我相信没有必要修改 timeamplitude 向量)。

index向量用来存储index/positiontime向量值从小到大排序,所以对于time={5, 16, 4, 7}:

index[0] will contain the index of the smallest value from time (which is 4, at position 2), hence index[0]=2

index[1] will contain the index of the 2nd smallest value from time (which is 5, at position 0), hence index[1]=0

etc.

并且由于 amplitude 的顺序基于 time,您可以在构建树时使用 index[pos] 访问两个向量:

time[index[pos]] and amplitude[index[pos]]

修改后的代码:

#include <iostream>
#include <vector>
#include <algorithm>

int  main(){

    std::vector<int> time={5, 16, 4, 7};
    std::vector<int> amplitude={10,17,8,16};
    std::vector<int> index(time.size(), 0);

    for (int i = 0 ; i != index.size() ; i++) {
        index[i] = i;
    }

    sort(index.begin(), index.end(),
         [&](const int& a, const int& b) {
            return (time[a] < time[b]);
          }
    );

    std::cout << "Time \t Ampl \t idx" << std::endl;
    for (int ii = 0 ; ii != index.size() ; ++ii) {
        std::cout << time[index[ii]] << " \t " << amplitude[index[ii]] << " \t " << index[ii] << std::endl;
    }
}

输出:

Time     Ampl    idx
4        8       2
5        10      0
7        16      3
16       17      1

But not only does it not work, it gives me something different each time

发生这种情况是因为 lambda 接收的参数来自 data2={10,17,8,16},并且这些值被用作索引以访问 return (data[a] < data[b]) 处的 data 向量。它导致了一些随机排序,因为它正在访问向量的范围并从内存中读取垃圾(因此是随机行为)。