c++: передача внешних параметров при поиске значений в векторе (при определённом операторе <, >)

202
07 апреля 2019, 21:30

Подскажите, как более правильнее и элегантнее решить следующую задачу:

исходные данные:

у меня есть структура:

struct object_t
{
    int     m_id = -1;
    int     m_pos = -1;
};

есть вектор данных:

using data_t = std::vector<object_t>;

а также есть внешний словарь слов

using dictionary_t = std::vector<std::string>;

в указанной структуре m_id - номер слова в словаре, а m_pos - позиция символа

задача:

необходимо найти в указанном векторе данных data_t запись, для которой выполнялись бы условия:

  1. это слово максимальной длины
  2. иначе это слово с минимальным значением позиции m_pos
  3. иначе это слово с минимальным значением символа по указанной позиции m_pos

реализация:

сейчас это у меня сделано в лоб:

data_t::const_iterator optimalData = mydata.cbegin();   
for (data_t::const_iterator localData = mydata.cbegin(); localData != mydata.cend(); localData++)
{
    if (mydictionary[localData->m_id].size() > mydictionary[optimalData->m_id].size())
        optimalData = localData;
    else if (mydictionary[localData->m_id].size() == mydictionary[optimalData->m_id].size())
    {
        if (localData->m_pos < optimalData->m_pos)
            optimalData = localData;
        else if ((localData->m_pos == optimalData->m_pos) && (mydictionary[localData->m_id][localData->m_pos] < mydictionary[optimalData->m_id][optimalData->m_pos]))
            optimalData = localData;
    }
}

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

data_t::const_iterator optimalData = mydata.cbegin();   
for (data_t::const_iterator localData = mydata.cbegin(); localData != mydata.cend(); localData++)
{
    if (*localData > *optimalData)
        optimalData = localData;
}

или даже средствами STL (вроде там была возможность найти максимальное значение поэтому получилась бы вообще одна строчка кода)

проблема

проблема реализации лишь в том как красиво и корректно передать mydictionary, который необходим для выполнения операции сравнения

вопрос

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

Answer 1

Используйте std::max_element. В качестве функции-компаратора используйте лямбду, map'у захватывайте по ссылке.

Пример:

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
struct object_t {
    int o_idx;  // index
    int o_pri;  // priority
};
bool operator<(const object_t& _l, const object_t& _r);
std::ostream& operator<<(std::ostream&, const object_t& _o);
int main() {
    std::vector<object_t> obj_list { { 0, 100 }, { 1, 101 }, { 2, 100 } };
    std::map<int, std::string> str_map = {
        { 0, "fooX" },
        { 1, "fooY" },
        { 2, "fooY" }
    };
    auto max_elm = 
        std::max_element(obj_list.cbegin(), obj_list.cend(), [&str_map](const auto& _l, const auto& _r) {
            return str_map[_l.o_idx] == str_map[_r.o_idx] ?
                _l < _r : str_map[_l.o_idx] < str_map[_r.o_idx];
    });
    if (obj_list.cend() != max_elm) {
        std::cout << *max_elm;
        std::cout << "str: " << str_map[max_elm->o_idx] << std::endl;
    }
    return 0;
}
bool operator<(const object_t& _l, const object_t& _r) {
    return _l.o_pri < _r.o_pri;
}
std::ostream& operator<<(std::ostream& _s, const object_t& _o) {
    return _s << "idx: " << _o.o_idx << " nice: " << _o.o_pri << std::endl;
}
READ ALSO
буквенный поиск в vector

буквенный поиск в vector

При создании кнопки поиска компилятор выдает ошибку:

272
Помогите удалить строку [закрыт]

Помогите удалить строку [закрыт]

На просторах интернета нашёл такой код, но он почему-то не пашет:

149
Оператор if внутри else [закрыт]

Оператор if внутри else [закрыт]

Написал данный код, он что то не работает:

169