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是一個很常用的標準容器,採用紅黑樹或者平衡二叉樹來儲存節點內容,具有對數複雜度的插入時間和查找時間。這裏簡單說下它的一些值得注意的關注點。
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]返回這個string的reference;然後調用這個空string的assignment運算符,把"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/