#c #c 20
Вопрос:
У меня есть фиксированное число (5) векторов структур (структуры вставляются во время выполнения, число может варьироваться). И у меня есть a enum class
, который используется в качестве ключа для поиска. Например.
enum class CountryCode { kUS, // ...other 4 }; const std::vectorlt;SomeStructgt;amp; get_by_country_code(CountryCode cc);
Я могу использовать std::unordered_maplt;CountryCode, std::vectorlt;SomeStructgt;, CustomHashgt;
пользовательский хэш, но я думаю, что это не стоит для коллекции фиксированного размера, порядок которой известен до выполнения. Каков был бы наиболее эффективный способ сохранить эти 5 векторов и выполнить поиск по enum
значению?
Я также думаю о std::tuple
том, но в моем случае ценности не являются разнородными.
Комментарии:
1. Если перечислители имеют значения по умолчанию, разве вы не можете просто использовать массив?
2. @DavisHerring считает ли массив векторов хорошей практикой?
3. По определению, это подходящая структура данных для коллекции объектов фиксированного размера с быстрым поиском по индексу. Если ты хочешь быть модным, ты мог бы положить их в
std::array
, я думаю?4. Зачем вам нужно использовать пользовательский хэш? Операция хэширования применяется к КЛЮЧУ, а не к ЗНАЧЕНИЮ. И перечисления в основном являются int с операцией хэширования по умолчанию, которая очень близка к тому, чтобы быть неоперативной. Так что unordered_maplt;Код страны, векторlt;SomeStructgt;` — это абсолютно правильный путь.
5. @senloa — это абсолютно соответствует int.
Ответ №1:
Какой был бы наиболее эффективный способ сохранить эти 5 векторов и выполнить поиск по значению перечисления?
Массив. Значения по умолчанию для перечисления равны 0,1,… которые идеально подходят в качестве индексов массива.
Единственным небольшим препятствием является то, что классы перечислений должны быть явно преобразованы в базовое целое число.
считается ли массив векторов хорошей практикой?
В них нет ничего особенно плохого.
Если размеры векторов известны одновременно и они не меняются после создания, то есть более эффективное решение: используйте один вектор, содержащий все объекты, разделенные кодом страны. Затем используйте массив пролетов для подпроекторов.
Комментарии:
1. не могли бы вы, пожалуйста, добавить код, обрезанный для случая
std::span
, о котором вы упомянули? тнх
Ответ №2:
#include lt;iostreamgt; #include lt;vectorgt; #include lt;cstdintgt; #include lt;arraygt; using namespace std; const int k_MAX_COUNTRY_CODE = 5; enum class CountryCode: uint8_t { COUNTRY_CODE_0 = 0, COUNTRY_CODE_1 = 1, COUNTRY_CODE_2 = 2, COUNTRY_CODE_3 = 3, COUNTRY_CODE_4 = 4, }; void printVector(vectorlt;intgt;amp; f_vec){ for(autoamp; el : f_vec){ cout lt;lt; el lt;lt; " "; } cout lt;lt; "n"; } int main() { CountryCode l_countryCode; arraylt;vectorlt;intgt;, k_MAX_COUNTRY_CODEgt; l_lookUP; vectorlt;intgt; l_lookUP(k_MAX_COUNTRY_CODE); for(int i = 0; i lt; k_MAX_COUNTRY_CODE; i ){ vectorlt;intgt; tempVec((i 1)*2 , i 534); l_lookUP[i] = tempVec; } printVector(l_lookUP[static_castlt;intgt;(CountryCode::COUNTRY_CODE_4)]); printVector(l_lookUP[static_castlt;intgt;(CountryCode::COUNTRY_CODE_3)]); printVector(l_lookUP[static_castlt;intgt;(CountryCode::COUNTRY_CODE_1)]); printVector(l_lookUP[static_castlt;intgt;(CountryCode::COUNTRY_CODE_2)]); return 0; }
Как и предлагал @eerorika, я бы также использовал массив для быстрого поиска. Я надеюсь, это было бы полезно.