c++ - 如何查找給定的鍵是否存在於C ++ std :: map中


我試圖檢查給定的鍵是否在地圖上,有些不能這樣做:

typedef map<string,string>::iterator mi;
map<string, string> m;
m.insert(make_pair("f","++--"));
pair<mi,mi> p = m.equal_range("f");//I'm not sure if equal_range does what I want
cout << p.first;//I'm getting error here

那我該如何打印p中的內容呢?


Answers



使用map::find

if ( m.find("f") == m.end() ) {
  // not found
} else {
  // found
}



要檢查映射中的特定鍵是否存在,請使用以下某種方法使用count成員函數:

m.count(key) > 0
m.count(key) == 1
m.count(key) != 0

map::find文檔說:“另一個成員函數map::count可以用來檢查一個特定的鍵是否存在。”

map::count文檔說:“因為地圖容器中的所有元素都是唯一的,所以函數只能返回1(如果找到元素)或者返回0(否則)。

要通過您知道存在的鍵從地圖中檢索值,請使用map :: at

value = m.at(key)

map :: operator []不同 ,如果指定的鍵不存在, map::at將不會在映射中創建新的鍵。




你可以使用.find()

map<string,string>::iterator i = m.find("f");

if (i == m.end()) { /* Not found */ }
else { /* Found, i->first is f, i->second is ++-- */ }



m.find == m.end() // not found 

如果你想使用其他的API,那麼找到m.count(c)>0

 if (m.count("f")>0)
      cout << " is an element of m.\n";
    else 
      cout << " is not an element of m.\n";



我想你想要map::find 。 如果m.find("f")等於m.end() ,那麼找不到密鑰。 否則,find會返回一個指向找到的元素的迭代器。

該錯誤是因為p.first是一個迭代器,它不適用於流插入。 把你最後一行cout << (p.first)->first;p是一對迭代器, p.first是一個迭代器, p.first->first是關鍵字符串。

一個映射只能有一個給定的鍵的元素,所以equal_range不是很有用。 它是為map定義的,因為它是為所有的關聯容器定義的,但是它對於multimap更有趣。




在比較查找結果和地圖'm'的結尾時要小心,因為所有的答案都已經完成了上面的map:iterator i = m.find(“f”);

 if (i == m.end())
 {
 }
 else
 {
 }  

如果其等於m.end(),則不應嘗試執行任何操作,如使用迭代器i打印鍵或值,否則將導致分段錯誤。




map<string, string> m;

檢查鍵是否存在,並返回發生的數字(地圖中的0/1):

int num = m.count("f");  
if (num>0) {    
    //found   
} else {  
    // not found  
}

檢查鍵是否存在,並返回迭代器:

map<string,string>::iterator mi = m.find("f");  
if(mi != m.end()) {  
    //found  
    //do something to mi.  
} else {  
    // not found  
}  

在你的問題中, operator<<重載導致的錯誤,因為p.firstmap<string, string> ,你不能打印出來。 嘗試這個:

if(p.first != p.second) {
    cout << p.first->first << " " << p.first->second << endl;
}



template <typename T, typename Key>
bool key_exists(const T& container, const Key& key)
{
    return (container.find(key) != std::end(container));
}

當然,如果你想變得更漂亮,你總是可以模仿一個函數,也可以找到一個函數和一個沒有找到的函數,像這樣:

template <typename T, typename Key, typename FoundFunction, typename NotFoundFunction>
void find_and_execute(const T& container, const Key& key, FoundFunction found_function, NotFoundFunction not_found_function)
{
    auto& it = container.find(key);
    if (it != std::end(container))
    {
        found_function(key, it->second);
    }
    else
    {
        not_found_function(key);
    }
}

像這樣使用它:

    std::map<int, int> some_map;
    find_and_execute(some_map, 1,
        [](int key, int value){ std::cout << "key " << key << " found, value: " << value << std::endl; },
        [](int key){ std::cout << "key " << key << " not found" << std::endl; });

這樣做的缺點是有一個好名字,“find_and_execute”是尷尬的,我不能拿出更好的東西在我的頭頂...




比較std :: map :: find和std :: map :: count的代碼,我會說第一個可能會產生一些性能優勢:

const_iterator find(const key_type& _Keyval) const
    {   // find an element in nonmutable sequence that matches _Keyval
    const_iterator _Where = lower_bound(_Keyval); // Here one looks only for lower bound
    return (_Where == end()
        || _DEBUG_LT_PRED(this->_Getcomp(),
            _Keyval, this->_Key(_Where._Mynode()))
                ? end() : _Where);
    }

size_type count(const key_type& _Keyval) const
    {   // count all elements that match _Keyval
    _Paircc _Ans = equal_range(_Keyval); // Here both lower and upper bounds are to be found, which is presumably slower.
    size_type _Num = 0;
    _Distance(_Ans.first, _Ans.second, _Num);
    return (_Num);
    }



如果你想比較一下地圖,你可以使用這個方法:

typedef map<double, double> TestMap;
TestMap testMap;
pair<map<double,double>::iterator,bool> controlMapValues;

controlMapValues= testMap.insert(std::pair<double,double>(x,y));
if (controlMapValues.second == false )
{
    TestMap::iterator it;
    it = testMap.find(x);

    if (it->second == y)
    {
        cout<<"Given value is already exist in Map"<<endl;
    }
}

這是一個有用的技術。