std::map C++

std::map C++

C++ Builder 2010-06-04 11:37:53 閱讀226 評論0   字號: 訂閱

std::map 再學習

1.         map中的元素其實就是一個pair

2.         map的鍵一般不能是指針,比如int*char*之類的,會出錯。常用的就用string了,int也行。

3.         map是個無序的容器,而vector之類是有序的。所謂有序無序是指放入的元素並不是按一定順序放進去的,而是亂序,隨機存放的(被映射後近似隨機存放)。所以遍歷的時候有些效率差別。

4.         判斷有沒有找到該鍵的內容可以這樣:

//-----------------------------------------------------------------------------------------------

std::map<std::string, Record>::const_iterator cIter;

cIter = stdfile.m_map.find(s);

if (cIter == stdfile.m_map.end())  //沒找到就是指向END

{

m_vecMoreFile.push_back(s);

}

//-----------------------------------------------------------------------------------------------

如果鍵的內容是指針的話, 應該用NULL指針也可以判斷了.

5.         遍歷:

//-----------------------------------------------------------------------------------------------

std::map<std::string,Record>::iterator iter;

for (iter = m_map.begin(); iter != m_map.end(); iter++)

{

std::string s = iter->second.filename;

}

//-----------------------------------------------------------------------------------------------

由於map內容可以相當一個PAIR,那就簡單了,用iter->second就可以取得值了。

 

std::map的一些注意點

std::map是一個很常用的標準容器,採用紅黑樹或者平衡二叉樹來儲存節點內容,具有對數複雜度的插入時間和查找時間。這裏簡單說下它的一些值得注意的關注點。

1.         插入:

//-----------------------------------------------------------------------------------------------

std::map<int, std::string> str_map;

str_map.insert ( std::pair<const int, std::string>(2, "bb") );      //沒有轉型操作

str_map.insert ( std::pair<int, std::string>(2, "bb") );     //需要轉型成std::pair<const int, std::string>再進行插入

str_map.insert ( std::make_pair(3, "cc") );          //同上,需要轉型

str_map.insert ( std::map<int, std::string>::value_type ( 4 , "dd" ) );      //沒有轉型操作

//-----------------------------------------------------------------------------------------------

還有一種方法是通過索引器[]去直接插入,這種方法在下邊再討論。

2.         刪除:

一種很常見的錯誤是:

//-----------------------------------------------------------------------------------------------

for ( map<int, string>::iterator it = str_map.begin(); it!=str_map.end(); it++ )

{

       if ( some_condition ) str_map.erase(it);

}

//-----------------------------------------------------------------------------------------------

刪除操作會使it亂掉,再使用it++就出錯了。

正確的做法是:

//-----------------------------------------------------------------------------------------------

for ( map<int, string>::iterator it = str_map.begin(); it!=str_map.end(); )

{

       if ( some_condition ) {

              str_map.erase(it++);

       } else {

              it++;

       }

}

//-----------------------------------------------------------------------------------------------

3.         索引:

str_map[5] = "ee";

這條語句實際上是分兩個步驟執行的:先在str_map[5]的地方構造一個空string,然後通過str_map[5]返回這個stringreference;然後調用這個空stringassignment運算符,把"ee"賦給它。因此,這樣寫要比直接insert效率低些。

索引還有一個問題是需要注意的:

//-----------------------------------------------------------------------------------------------

map<int, string> m;

cout<<m.size()<<endl; // output: 0

if ( m[4] == "aa" ) some_operation();

cout<<m.size()<<endl; //output: 1

//-----------------------------------------------------------------------------------------------

這裏m[4]已經指向了一個構造好了的空string

4.         function object

std::mem_fun的幫助下,vector等容器可以很容易地使用find_if等泛型算法,比如:

class X {

public:

       bool condition();

};

vector<X> vx;

....

vector<X>::iterator it = std::find_if ( vx.begin(), vx.end(), std::mem_fun(&X::condition) );

由於map::iterator指向的是std::pair,所以要使用這些算法大部分時候就只好自己手寫相應的function object了。

但藉助boost lambda庫的幫助,我們就可以省去自己寫function object的麻煩了:

#include <boost/lambda/bind.hpp>

#include <boost/lambda/lambda.hpp>

using boost::lambda::bind; 

std::map<int, X> mx;

....

std::map<int, X>::iterator it = find_if ( mx.begin(), mx.end(),

       bind ( &X::condition, bind(&std::map<int, X>::value_type::second, _1) ) );

 

 

 

 

轉自:http://blog.163.com/andy-su/blog/static/28174174201054113753538/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章