Как построить вектор кортежей и отсортировать их как пару? - PullRequest
0 голосов
/ 30 апреля 2018

Предположим, у меня есть несколько целочисленных элементов, подобных этому:

(3 9 1), (1 5 2), (2 8 3), (1 4 4), (1 6 5), (1 5 6)

Теперь я хочу отсортировать элементы, как отсортированы векторные пары. Разница лишь в том, что вместо 2 ключей у нас есть 3 ключа. После сортировки элементы будут выглядеть так:

(1 4 4), (1 5 2), (1 5 6), (1 6 5), (2 8 3), (3 9 1)

Есть ли STL или другие методы для достижения этой цели? Я узнал о Tuples, но у меня возникли некоторые проблемы, чтобы хорошо это понять.
Ребята, можете ли вы мне чем-нибудь помочь, пожалуйста? Может быть, путем предоставления полезных ссылок или объяснения процесса.

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

A vector из tuple можно отсортировать, используя только STL, если хотите.

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

int main(int argc, char * argv[]){

    std::vector< std::tuple<int, int, int> > myVec;

    myVec.emplace_back(3, 9, 1);
    myVec.emplace_back(1, 5, 2);
    myVec.emplace_back(2, 8, 3);
    myVec.emplace_back(1, 4, 4);
    myVec.emplace_back(1, 6, 5);
    myVec.emplace_back(1, 5, 6);

    std::sort(myVec.begin(), myVec.end());

    for (auto i : myVec){
        std::cout << std::get<0>(i) << ", " << std::get<1>(i) << ", " << std::get<2>(i) << '\n';
    }

    return 0;
}

Это пример из здесь , только что измененного с вашими значениями.

Как это работает, новый tuple создается с emplace_back и добавляется в конец вектора. Вы можете использовать push_back(std::make_tuple(..., если хотите, но это кажется слишком сложным. Тогда вы sort vector, как и любой другой vector. Поведение по умолчанию sort - восходящее. Вы можете изменить поведение sort, добавив свой собственный comp. Аргументы вашей функции сравнения будут 2 tuple с. Тип возврата - логический результат вашего сравнения. Поскольку tuple s уже имеет все сравнения (<, >, <= и т. Д.), Вам не нужно переопределять их. Вы также можете использовать это для сравнения разнородных вещей, это только усложняется.

bool myFunction(const std::tuple<int, int, int> &i, const std::tuple<int, int, int> &j) {
    return i > j;
}

....
std::sort(myVec.begin(), myVec.end(), myFunction);
....

И это отсортирует вектор в порядке убывания. Вы также можете заменить myFunction на лямбду.

std::sort(myVec.begin(), myVec.end(), [](const std::tuple<int, int, int> &i, const std::tuple<int, int, int> &j) {
    return i > j;
});
0 голосов
/ 30 апреля 2018

Я предлагаю два решения: первое использование пользовательской структуры с использованием пользовательского оператора <, который использует std::tie для сравнения трех целых чисел по порядку, а второе использование std::tuple .

#include <iostream>
#include <set>
#include <vector>

struct three_integers {
  int a, b, c;
  bool operator<(const three_integers &other) const {
    return std::tie(a, b, c) < std::tie(other.a, other.b, other.c);
  }
};

int main(int argc, char *argv[]) {

  // 1st solution using a custom structure
  // std::set containers are always ordered according to the < operator
  std::set<three_integers> sorted_set = {{3, 9, 1}, {1, 5, 2}, {2, 8, 3},
                                         {1, 4, 4}, {1, 6, 5}, {1, 5, 6}};

  std::cout << "Sorted set:\n";
  for (auto &element : sorted_set) {
    std::cout << "(" << element.a << " " << element.b << " " << element.c << ")"
              << std::endl;
  }

  std::vector<three_integers> sorted_vector = {{3, 9, 1}, {1, 5, 2}, {2, 8, 3},
                                               {1, 4, 4}, {1, 6, 5}, {1, 5, 6}};

  // std::vector is not ordered, so we call std::sort on it to make it just like
  // std::set, it will use our custom < operator
  std::sort(sorted_vector.begin(), sorted_vector.end());

  std::cout << "Sorted vector:\n";
  for (auto &element : sorted_vector) {
    std::cout << "(" << element.a << " " << element.b << " " << element.c << ")"
              << std::endl;
  }

  // 2nd solution using tuples
  std::vector<std::tuple<int, int, int>> sorted_vector_tuple = {
      {3, 9, 1}, {1, 5, 2}, {2, 8, 3}, {1, 4, 4}, {1, 6, 5}, {1, 5, 6}};

  std::sort(sorted_vector_tuple.begin(), sorted_vector_tuple.end());

  std::cout << "Sorted vector of tuples:\n";
  for (auto &element : sorted_vector_tuple) {
    std::cout << "(" << std::get<0>(element) << " " << std::get<1>(element)
              << " " << std::get<2>(element) << ")" << std::endl;
  }

  return 0;
}

выход

Sorted set:
(1 4 4)
(1 5 2)
(1 5 6)
(1 6 5)
(2 8 3)
(3 9 1)
Sorted vector:
(1 4 4)
(1 5 2)
(1 5 6)
(1 6 5)
(2 8 3)
(3 9 1)
Sorted vector of tuples:
(1 4 4)
(1 5 2)
(1 5 6)
(1 6 5)
(2 8 3)
(3 9 1)

Я рекомендую вам прочитать документацию std::sort.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...