Как получить все ключи из заданного значения 3D-карты? - PullRequest
0 голосов
/ 05 октября 2011

У меня есть контейнер 3D-карты, объявленный следующим образом:

std::map<std::string, std::map<std::string, std::map<std::string, CGridItem*> > > m_3DGridItems;

Предположим, у меня есть значение указателя на объект CGridItem. Как мне эффективно получить все три строки ключа карты? Спасибо!

Ответы [ 3 ]

2 голосов
/ 05 октября 2011

Прежде всего, вам действительно нужен такой неуклюжий контейнер?

Было бы намного проще иметь структуру Key:

struct Key {
  std::string x;
  std::string y;
  std::string z;
};

А затем определите порядок на Key:

bool operator<(Key const& left, Key const& right) {
  if (left.x < right.x) { return true; }
  if (left.x > right.x) { return false; }

  if (left.y < right.y) { return true; }
  if (left.y > right.y) { return false; }

  return left.z < right.z;
}

Тогда вы можете иметь гораздо более простую структуру для манипулирования:

std::map<Key, GridItem*>

Если вам нужно сопоставить оба пути, посмотрите Boost.Bimap , который поддерживает двустороннее сопоставление Key <-> GridItem* (так что вам не нужно синхронизировать две структуры самостоятельно).

0 голосов
/ 05 октября 2011

Во-первых: если вы в первую очередь делаете поиск подобным образом, эта структура данных определенно не самая эффективная альтернатива.

Я не вижу другого способа, кроме как сделать три вложенных цикла for, поскольку карта размечена для поиска по ключу, а не по значению. Это будет выглядеть примерно так:

std::map<std::string, std::map<std::string, std::map<std::string, CGridItem*> > >:iterator it1;
CGridItem* obj = ...;
for(it1 = mymap.begin(); it != mymap.end(); ++it1)
{
    std::map<std::string, std::map<std::string, CGridItem*> > it2;
    for(it2 = it1->second.begin(); it2 != it->second.end(); ++it2)
    {
        std::map<std::string, CGridItem*> it3;
        for(it3 = it2->second.begin(); it3 != it2->second.end(); ++it3)
        {
            if(it3->second == obj) {
                /*found it!*/
                /* your 3 strings are in it1->first, it2->first, it3->first */
            }
        }
    }
}

РЕДАКТИРОВАТЬ: Я предлагаю следующую структуру данных:

std::map<CGridItem*, std::tuple<std::string, std::string, std::string> > mymap;

Это сопоставляет ваш CGridItem объект с 3 строками. Примечание: std::tuple может быть недоступен, если вы не используете c ++ 11, но он доступен в boost библиотеки .

0 голосов
/ 05 октября 2011

Вы можете просто использовать итератор, чтобы получить все ключи / значения на карте.Когда значение также является картой, вы можете получить ключ / значения таким же образом ...

...