Эффективный поиск по фиксированной коллекции векторов

#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, я бы также использовал массив для быстрого поиска. Я надеюсь, это было бы полезно.