Как использовать станд.:: вид с вектором структур и сравнивает функцию?

Вы можете реализовать вспомогательную функцию для преобразования.

function convertRoundsToLeaderBoard(rounds) {
    var indexes = {};
    var leaderBoard = [];
    for (var round of rounds) {
        if (indexes[round.team] === undefined) {
            indexes[round.team] = leaderBoard.length;
            leaderBoard.push({
                team: round.team,
                rounds: [{score: round.score, course: round.course}]
            });
        } else {
            leaderBoard[indexes[round.team]].rounds.push({score: round.score, course: round.course});
        }
    }
    return leaderBoard;
}

Давайте проверим это:

convertRoundsToLeaderBoard(
[
   {
      team: "Dropkick Murphies",
      score: 75,
      course: 17
   },
   {
      team: "Dropkick Murphies",
      score: 62,
      course: 24
   },
   {
      team: "Dropkick Murphies",
      score: 69,
      course: 26
   },
   {
      team: "Gigantic",
      score: 67,
      course: 26
   },
   {
      team: "Gigantic",
      score: 65,
      course: 17
   },
   {
      team: "Gigantic",
      score: 63,
      course: 24
   }
]);
11
задан Community 23 May 2017 в 11:59
поделиться

2 ответа

std::sort берет другое, сравнивают функцию от используемого в qsort. Вместо того, чтобы возвратиться –1, 0 или 1, эта функция, как ожидают, возвратит a bool значение, указывающее, является ли первый элемент меньше, чем второе.

У Вас есть две возможности: реализация operator < для Ваших объектов; в этом случае, значение по умолчанию sort вызов без третьего аргумента будет работать; или можно переписать Ваш выше функции для выполнения того же самого.

Заметьте, что необходимо использовать строгий контроль типов в аргументах.

Кроме того, хорошо не использовать функцию здесь вообще. Вместо этого используйте функциональный объект. Они извлекают выгоду из встраивания.

struct pkt_less {
    bool operator ()(pkt const& a, pkt const& b) const {
        if (a.alfa < b.alfa) return true;
        if (a.alfa > b.alfa) return false;

        if (a.x < b.x) return true;
        if (a.x > b.x) return false;

        return false;
    }
};

// Usage:

sort(wektor.begin(), wektor.end(), pkt_less());
25
ответ дан 3 December 2019 в 01:45
поделиться

В C++ можно использовать функторы как boost::bind которые делают это задание приятно:

#include <vector>
#include <algorithm>

struct pkt {
    double x;
    double y;
    double alfa;
    pkt(double x, double y, double alfa)
        :x(x), y(y), alfa(alfa) { }
};

int main() {
    std::vector<pkt> p;
    p.push_back(pkt(10., 0., 20.));
    p.push_back(pkt(10,  0., 30.));
    p.push_back(pkt(5.,  0., 40.));

    std::sort(p.begin(), p.end(), 
              boost::bind(&pkt::alfa, _1) <  boost::bind(&pkt::alfa, _2) || 
              boost::bind(&pkt::alfa, _1) == boost::bind(&pkt::alfa, _2) && 
              boost::bind(&pkt::x,    _1) <  boost::bind(&pkt::x,    _2));
}

Если необходимо много раз делать это, можно также решить проблему путем создания функционального объекта, который принимает членские указатели и делает вид. Можно снова использовать его для любого вида объекта и участников. Сначала, как Вы используете его:

int main() {
    /* sorting a vector of pkt */
    std::vector<pkt> p;
    p.push_back(pkt(10., 0., 20.));
    p.push_back(pkt(5.,  0., 40.));

    std::sort(p.begin(), p.end(), make_cmp(&pkt::x, &pkt::y));
}

Вот код для make_cmp. Не стесняйтесь разрывать его (использование boost::preprocessor):

#include <boost/preprocessor/repetition.hpp>
#include <boost/preprocessor/facilities/empty.hpp>

// tweak this to increase the maximal field count
#define CMP_MAX 10

#define TYPEDEF_print(z, n, unused) typedef M##n T::* m##n##_type;
#define MEMBER_print(z, n, unused) m##n##_type m##n;
#define CTORPARAMS_print(z, n, unused) m##n##_type m##n
#define CTORINIT_print(z, n, unused) m##n(m##n)

#define CMPIF_print(z, n, unused)              \
    if ((t0.*m##n) < (t1.*m##n)) return true;  \
    if ((t0.*m##n) > (t1.*m##n)) return false; \

#define PARAM_print(z, n, unused) M##n T::* m##n

#define CMP_functor(z, n, unused)                                       \
    template <typename T                                                \
              BOOST_PP_ENUM_TRAILING_PARAMS(n, typename M)>             \
    struct cmp##n {                                                     \
        BOOST_PP_REPEAT(n, TYPEDEF_print, ~)                            \
        BOOST_PP_REPEAT(n, MEMBER_print, ~)                             \
        cmp##n(BOOST_PP_ENUM(n, CTORPARAMS_print, ~))                   \
            BOOST_PP_IF(n, :, BOOST_PP_EMPTY())                         \
            BOOST_PP_ENUM(n, CTORINIT_print, ~) { }                     \
                                                                        \
        bool operator()(T const& t0, T const& t1) const {               \
            BOOST_PP_REPEAT(n, CMPIF_print, ~)                          \
            return false;                                               \
        }                                                               \
    };                                                                  \
                                                                        \
    template<typename T                                                 \
             BOOST_PP_ENUM_TRAILING_PARAMS(n, typename M)>              \
    cmp##n<T BOOST_PP_ENUM_TRAILING_PARAMS(n, M)>                       \
        make_cmp(BOOST_PP_ENUM(n, PARAM_print, ~))                      \
    {                                                                   \
        return cmp##n<T BOOST_PP_ENUM_TRAILING_PARAMS(n, M)>(           \
            BOOST_PP_ENUM_PARAMS(n, m));                                \
    }

BOOST_PP_REPEAT(CMP_MAX, CMP_functor, ~)


#undef TYPEDEF_print
#undef MEMBER_print
#undef CTORPARAMS_print
#undef CTORINIT_print
#undef CMPIF_print
#undef PARAM_print
#undef CMP_functor
7
ответ дан 3 December 2019 в 01:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: