C ++ вложенные карты поиска другого типа во время выполнения - PullRequest
2 голосов
/ 17 февраля 2020

Мне нужно преобразовать объект поиска из нескольких столбцов из Java в C ++ 14 (C ++ 17 или повышение не учитывают ie: вариант / любой).

Поиск данные загружаются во время выполнения (из CSV или json) и могут содержать 4 типа std::string, int, double, long long. Файл может содержать от 2 до N столбцов. Ниже приведен простой пример:

Country    Dept  Ratio   Final
"FR"        75     1.25    12
"FR"        01     0.25    15
"UK"        24     1.5     7
....

Цель состоит в том, чтобы найти конечное значение с использованием N-1 параметров (соответствующих каждому столбцу).

В каждом столбце (кроме конечного) содержится параметр "search" "это может быть =, <,>. Поиск всегда выполняется при равенстве, и если поиск не найден, а «поиск» равен <или>, мы используем наиболее близкое <или> совпадение.

Пример запроса выполняется таким способом поиска («FR», 72, 1.28 ) например.

В Java это реализовано с использованием вложенного TreeMap, что эквивалентно std :: map, но их можно создать во время выполнения (потому что это java).

До сих пор я использовал std::map, но моя реализация довольно тяжелая, так как она сделана с помощью вложенного класса, который Dynami c читает shared_ptr<void> et c ..

Я пытаюсь найти хороший «шаблонный способ» для реализации этого (используя std::map или что-то еще).

Любые советы приветствуются

РЕДАКТИРОВАТЬ: у нас может быть 1000 записей, моя идея состояла в том, чтобы сделать для приведенного выше примера данных, эквивалентного

std::map<std::string, std::map<int, std::map<double, int>>>

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

struct BaseDimension
{
}

template<typename X, typename Y>
struct Dimension: BaseDimension
{
    std::shared_ptr<std::map<X, Y>> _map;
}

Но у меня есть проблема организовать оттуда "Дерево", от BaseDimension, как динамически c приводить к Измерению, избегая переключения на все возможные пары типов.

Используя тот же образец данных, мы получили бы

Dimension<std::string, BaseDimension>
           Dimension<int ,BaseDimension>
                    Dimension<double, int>

Я только что нашел std :: вариант для C ++ 14 (mapbox), я проверю, облегчит ли это

1 Ответ

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

Если я правильно понимаю ваш вопрос, вы можете использовать std::tuple с операторами сравнения перегрузок ведьмы, вы можете использовать это в любом виде контейнера C ++, например std::map, std::vector и т. Д. c., Или ваш собственный контейнер.

Образец с использованием std::vector было бы:

Живой образец

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

//overloading << operator for std::cout
std::ostream& operator << (std::ostream& os, std::tuple<std::string, int, double, long long> t) {
    os << std::get<0>(t) << " " << std::get<1>(t) << " " << std::get<2>(t) << " " << std::get<3>(t);
    return os;
}

int main()
{
    std::vector<std::tuple<std::string, int, double, long long>> tuple_vector;

    tuple_vector.push_back(std::make_tuple("test string", 1, 1.2, 1));
    tuple_vector.push_back(std::make_tuple("string", 1, 1.0, 1));

    std::cout << (tuple_vector.at(0) == tuple_vector.at(1)) << " ";       //1 (true)
    std::cout << (tuple_vector.at(0) > tuple_vector.at(1)) << std::endl;  //0 (false)

    std::cout << tuple_vector.at(0); //using << overloaded << operator

}

Выход:

1 0
test string 1 1.2 1
...