温馨提示:本文翻译自stackoverflow.com,查看原文请点击:c++ - Sort one vector according to another
c++ root-framework sorting

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

发布于 2020-04-05 00:56:08

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

排序后如何获取索引排列

我有两个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] 
      }
}

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

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

提前致谢!

查看更多

提问者
Beth Long
被浏览
84
SPM 2020-02-02 09:40

确实,您可以重用共享链接中解决方案来解决问题。但是您需要继续构建index向量(我相信没有必要修改timeamplitude向量)。

index载体被用于存储索引/位置的的time排序从最小到最大矢量值,所以对于time={5, 16, 4, 7}

index[0]将包含来自的最小值的索引time4在位置2处),因此index[0]=2

index[1]将包含的第二个最小值的索引time5位于位置0),因此index[1]=0

等等

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

time[index[pos]]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

但不仅不起作用,而且每次都给我一些不同的东西

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