Значение проверки существует в std :: map – C ++

Я знаю, что метод find находит предоставленный ключ в std :: map и возвращает iterator элементу. Есть ли в любом случае, чтобы найти значение и получить iterator для элемента? Мне нужно сделать, чтобы проверить указанное значение на std :: map. Я сделал это, зациклив все элементы на карте и сравнив их. Но я хотел знать, есть ли для этого лучший подход.

Вот что я написал

bool ContainsValue(Type_ value) { bool found = false; Map_::iterator it = internalMap.begin(); // internalMap is std::map while(it != internalMap.end()) { found = (it->second == value); if(found) break; ++it; } return found; } 

редактировать

Как насчет использования другой карты внутри, которая хранит значение, комбинацию клавиш. Значит, я могу называть его? Является ли find () в std :: map, выполняющем последовательный поиск?

благодаря

Вы можете использовать boost :: multi_index для создания двунаправленной карты – вы можете использовать либо значение пары в качестве ключа для быстрого поиска.

Если у вас есть доступ к отличной библиотеке boost, вам следует использовать boost :: multi_index для создания двунаправленной карты, как говорит Марк. В отличие от std :: map, это позволяет вам искать ключ или значение.

Если у вас есть только STL, чтобы передать следующий код, он выполнит трюк (templated для работы с любым видом карты, где mapped_type поддерживает оператор ==):

 #include  #include  #include  #include  #include  template struct map_data_compare : public std::binary_function { public: bool operator() (typename T::value_type &pair, typename T::mapped_type i) const { return pair.second == i; } }; int main() { typedef std::map mapType; mapType map; map["a"] = 1; map["b"] = 2; map["c"] = 3; map["d"] = 4; map["e"] = 5; const int value = 3; std::map::iterator it = std::find_if( map.begin(), map.end(), std::bind2nd(map_data_compare(), value) ); if ( it != map.end() ) { assert( value == it->second); std::cout << "Found index:" << it->first << " for value:" << it->second << std::endl; } else { std::cout << "Did not find index for value:" << value << std::endl; } } 

Как насчет использования другой карты внутри, которая хранит значение, комбинацию клавиш. Значит, я могу называть его?

Да: поддерживайте две карты, одна карта использует один тип ключа, а другой – другой.

Является ли find () в std :: map, выполняющем последовательный поиск?

Нет, это двоичный поиск отсортированного дерева: его скорость равна O (log (n)).

Посмотрите на двунаправленные карты форсирования: http://www.boost.org/doc/libs/1_38_0/libs/bimap/doc/html/index.html

Он позволяет обеим значениям действовать как ключ.

В противном случае итерация – это путь.

попробуйте эту функцию:

 template  typename Map::const_iterator MapSearchByValue(const Map & SearchMap, const Val & SearchVal) { Map::const_iterator iRet = SearchMap.end(); for (Map::const_iterator iTer = SearchMap.begin(); iTer != SearchMap.end(); iTer ++) { if (iTer->second == SearchVal) { iRet = iTer; break; } } return iRet; } 

я думаю, что это полезно

Нет, вам нужно зациклиться на std :: map и проверить все значения вручную. В зависимости от того, что вы хотите сделать, вы можете перенести std :: map в простой class, который также кэширует все значения, которые вставляются в карту, в то, что легко найти и не позволяет дублировать, например, std ::задавать. Не наследуйте от std :: map (у него нет виртуального деструктора!), Но заверните его, чтобы вы могли сделать что-то вроде этого:

 WrappedMap my_map< std::string, double >; my_map[ "key" ] = 99.0; std::set< double > values = my_map.values(); // should give back a set with only 99.0 in it 

Альтернативой вашей собственной камере было бы использовать двунаправленную карту Boost, которая легко найти в сообщениях ниже или Google.

Это действительно зависит от того, что вы хотите делать, как часто вы хотите это сделать, и насколько сложно катить собственный небольшой class-оболочку против установки и использования Boost. Мне нравится Boost, так что это хороший способ – но есть что-то приятное и полное в создании собственного classа обертки. У вас есть преимущество в том, чтобы напрямую понять сложность операций, и вам может не понадобиться полное обратное отображение значений => ключей, которые предоставляются двунаправленной картой Boost.

То, что вы запрашиваете, именно то, что std :: find делает (не функция-член)

 template< class InputIt, class T > InputIt find( InputIt first, InputIt last, const T& value ); 

Не очень лучший вариант, но может быть полезен в немногих случаях, когда пользователь присваивает значение по умолчанию, например 0 или NULL при инициализации.

 Ex. < int , string > < string , int > < string , string > consider < string , string > mymap["1st"]="first"; mymap["second"]=""; for (std::map::iterator it=mymap.begin(); it!=mymap.end(); ++it) { if ( it->second =="" ) continue; } 

Возможно, я не совсем понимаю, чего вы пытаетесь достичь. Но чтобы просто проверить, содержит ли карта значение, я считаю, что вы можете использовать встроенную find std::map .

 bool ContainsValue(Type_ value) { return (internalMap.find(value) != internalMap.end()); } 
Давайте будем гением компьютера.