Трёхмерный массив с пропусками (C++, map)

275
14 июля 2018, 06:50

У меня есть трёхмерный массив с вот таким объявлением:

unordered_map<int, unordered_map<int, unordered_map<int, T*>>> &ll=data[0];

Как мне в нём создать, удалить, проверить наличие, пройтись по всему массиву? Я знаю пару способов, но они по 100 строк и очень неэффективны.

Answer 1
  • Создать и/или присвоить элемент по индексам [i][j][k] легко: простое обращение через операторы [] вам все само прекрасно создаст

    ll[i][j][k] = /* какое-то значение вашего типа `T *` */;
    
  • Проверить наличие по индексам [i][j][k] тоже легко, но более громоздко:

    if (auto iti = ll.find(i); iti != ll.end())
      if (auto itj = iti->second.find(j); itj != iti->second.end())
        if (auto itk = itj->second.find(k); itk != itj->second.end())
          /* Нашлось! Значение равно `itk->second` */;
    
  • Пройти по всем тоже несложно:

    for (const auto &pi : ll)
      for (const auto &pj : pi.second)
        for (const auto &pk : pj.second)
          /* Элемент `pk.second` с индексами [pi.first][pj.first][pk.first] */;
    
  • Удалить по индексам [i][j][k]: зависит от того, насколько рьяно вы хотите удалить все на данный момент не нужное, т.е. пустые подмапы. Самый агрессивно удаляющий все вариант, с проверкой существования удаляемого элемента:

    if (auto iti = ll.find(i); iti != ll.end())
      if (auto itj = iti->second.find(j); itj != iti->second.end())
        if (auto itk = itj->second.find(k); itk != itj->second.end())
        {
          /* Удаляем, если нужно, сам `T`, т.е. `itk->second` */
          itj->second.erase(itk);
          if (itj->second.empty())
          {
            iti->second.erase(itj);
            if (iti->second.empty())
              ll.erase(iti);
          }
        }
    

    Если же вы абсолютно уверены в существовании элемента [i][j][k], ваш T не требует удаления и вы не хотите заниматься ранним удалением пустых подмапов, то все можно сделать в одну строчку

    ll.find(i)->second.find(j)->second.erase(k);
    

Однако возможно, что вместо такого "трехэтажного" unordered_map вам бы лучше подошел обычный "одноэтажный" unordered_map, в котором в качестве ключа выступала бы тройка чисел (i, j, k) (std::tuple). Это многое бы упростило.

READ ALSO
Конструкторы классов

Конструкторы классов

Дословно вопрос звучит так "Define the constructor for class Z"Помогите разобраться что именно надо реализовать? Ну тип конструктор у класса Z уже есть, чего...

195
Интерфейсы и их реализация

Интерфейсы и их реализация

Не могу никак разобраться с интерфейсами и их реализациейОбьясните пожалуйста как их правильно реализовывать и как это хотя-бы примерно...

233
Непрозрачная графика на прозрачном Jframe

Непрозрачная графика на прозрачном Jframe

возникла необходимость отображения непрозрачной графики на прозрачном Jframe c использованием BufferStrategy (если это вообще возможно)

224