Сортировать один вектор по другому - PullRequest
0 голосов
/ 31 января 2020

Я основываю свой вопрос на ответе на этот вопрос:

Как получить перестановку индекса после сортировки

У меня есть два 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};

После завершения я хочу добавить оба упорядоченных вектора в ЦЕРН 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 ++, поэтому я надеюсь, что ответы не будут слишком техническими!

Заранее спасибо!

1 Ответ

0 голосов
/ 02 февраля 2020

Действительно, вы можете повторно использовать решение по ссылке, которой вы поделились, для решения вашей проблемы. Но вам нужно продолжать строить вектор index (и я считаю, что нет необходимости изменять векторы time или amplitude).

Вектор index используется для хранения индекс / позиция векторных значений time, отсортированных от наименьшего к наибольшему, поэтому для time={5, 16, 4, 7}:

index[0] будет содержаться индекс наименьшего значения из time ( 4 в позиции 2), следовательно, index[0]=2

index[1] будет содержать индекс 2-го наименьшего значения из time (то есть 5 в позиции 0), следовательно index[1]=0

et c.

И так как порядок 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

Но он не только не работает, он дает мне что-то другое каждый раз

Это произошло из-за параметров, которые лямбда был г eceiving from data2={10,17,8,16}, и эти значения использовались в качестве индекса для доступа к вектору data в return (data[a] < data[b]). Это вызвало некоторую случайную сортировку, потому что он обращался за пределы вектора и считывал мусор из памяти (отсюда случайное поведение).

...