Сравнение различных свойств класса в std :: vector класса - PullRequest
1 голос
/ 03 марта 2020

Я действительно не знал, какой будет правильный заголовок для этого, пожалуйста, потерпите меня.

Итак, представьте, что у меня есть такой класс:

class data {
    double a;
    double b;
    double c;

    bool is_blue;
};

и затем я использую его для построения вектора, std::vector<data> vdata. Что меня интересует, так это возможность сравнивать значения вектора на основе заданного свойства класса. Например, я хотел бы найти элемент с наименьшим a или найти все элементы с b > 2.0, или is_blue == true.

У меня есть несколько идей о том, как этого добиться, но они не охватывают все случаи, которые я хочу. Например, я, вероятно, могу l oop над элементами vdata, выбрать a и построить std::vector<double>, а затем использовать std::min_element, чтобы получить мин. Или используйте std::find, чтобы найти то, что я хочу.

Или, может быть, я могу использовать std::transform и лямбду и генерировать вектор, показывающий, прошел ли мой тест или нет, а затем выбрать из него, например:

std::vector<bool> s;
std::transform(s.begin(), s.end(), std::back_inserter(ordinals),
                   [](auto &d) -> bool { return d.b > 2.0 });

Я также подумал может быть, я могу использовать std::sort и в основном отсортировать vdata на основе того, что меня интересует. Я даже не уверен, имеет ли этот метод смысл.

Итак, я знаю, как подойти к этому в по-разному, и они работают, но я чувствую, что что-то упустил, и это должен быть лучший способ, который охватывает все случаи. В основном меня интересуют некоторые сравнения и элементы min / max. У меня также есть полный контроль над классом data, поэтому я могу свободно добавлять его, инкапсулировать в другой класс и т. Д. c.

PS Пожалуйста, дайте мне знать, если я смогу выбрать лучший заголовок для этого вопроса.

1 Ответ

2 голосов
/ 03 марта 2020

Для вещей, которые вы упоминаете, вы можете использовать функции в стандартной библиотеке. Вам понадобятся std::min_element (как вы упомянули) и std::partition (или std::stable_partition).

#include <algorithm> // min_element, partition

std::ostream& operator<<(std::ostream& os, const data& d) {
    return os << '{' << d.a << ',' << d.b << ',' << d.c << ',' << d.is_blue << '}';
}
//...

    std::cout << "element with smallest a\n";
    auto min_it = std::min_element(vdata.begin(), vdata.end(),
                                   [](const data& l, const data& r) { return l.a < r.a; });
    std::cout << *min_it << '\n';


    std::cout << "range with all b > 2.0\n";
    auto pivot = std::partition(vdata.begin(), vdata.end(),
                                [](const data& d) { return d.b > 2.; });
    for(auto it = vdata.begin(); it != pivot; ++it) {
        std::cout << *it << '\n';
    }


    std::cout << "range with all blue\n";
    pivot = std::partition(vdata.begin(), vdata.end(),
                           [](const data& d) { return d.is_blue; });
    for(auto it = vdata.begin(); it != pivot; ++it) {
        std::cout << *it << '\n';
    }

У меня есть несколько идей о том, как этого добиться, но они не охватывают все случаи, которые я хочу.

Существуют разные алгоритмы для разных сцен ios. Вы вряд ли найдете тот, который охватывает все случаи (за исключением некоторых тривиальных случаев, когда вы можете получить один бесплатно так сказать).

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