強大的STL(二)


********************************************************************************************************************************

string

********************************************************************************************************************************

方法

    string s = "hello"; 

    string 

        s1 = s.substr(0, 3), // "hel" 

        s2 = s.substr(1, 3), // "ell" 

        s3 = s.substr(0, s.length()-1),// "hell"

        s4 = s.substr(1); // "ello" 



********************************************************************************************************************************

set

********************************************************************************************************************************



set提供的功能:可以添刪元素,不允許相同元素存在,可以查元素總數,以及某個元素是否已存在

方法

--------------------

構造

int data[5] = { 5, 1, 4, 2, 3 }; 

set<int> s(data, data+5); 

--------------------

 set<int> s; 

 for(int i = 1; i <= 100; i++) {

      s.insert(i); // Insert 100 elements, [1..100] 

 }

 s.insert(42); // does nothing, 42 already exists in set 

 for(int i = 2; i <= 100; i += 2) { 

      s.erase(i); // Erase even values 

 } 

 int n = int(s.size()); // n will be 50 

--------------------

 set 沒有push_back方法,

--------------------

 循環遍歷

 int r = 0; 

 for(set<int>::const_iterator it = S.begin(); it != S.end(); it++) { 

      r += *it; 

 } 

--------------------

查找,可以使用STL提供的find方法(複雜度爲O(n)),而set::find()複雜度爲 O(log(n))

 set<int> s; 

 // ... 

 if(s.find(42) != s.end()) { 

      // 42 presents in set 

 } 

 else { 

      // 42 not presents in set 

 } 

 或

 if(s.count(42) != 0) { 

      // … 

 }  

 或

 if(s.count(42)) { 

      // … 

 } 

--------------------

 區間擦除

 set<int>::iterator it1, it2; 

 it1 = s.find(10); 

 it2 = s.find(100); 

 s.erase(it1, it2);

--------------------

非常簡單但是有用的方法:去除vector中重複的項,並排好序(升序)  

  vector<int> v; 

 // … 

 set<int> s(v.begin(), v.end()); 

 vector<int> v2(s.begin(), s.end()); //vc無法編譯通過,用下代替



    for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)

        v2.push_back(*it);



********************************************************************************************************************************

map

********************************************************************************************************************************

map與set很相似,但是map存放的是pairs <key, value>而不是值,

map確保對應一個明確的key最多隻存在一個pair(即key不重複,同set的value),並且map可以使用操作符[]。



不要通過iterator來改變map的key,因爲這會破壞map的內部數據結構。



 map<string, int> M; 

 M["Top"] = 1; 

 M["Coder"] = 2; 

 M["SRM"] = 10; 



 int x = M["Top"] + M["Coder"]; 



 if(M.find("SRM") != M.end()) { 

      M.erase(M.find("SRM")); // or even M.erase("SRM") 

 } 





map::find() 和 map::operator []. 有一個很重要的不同就是,map::find()不會改變map的內容,operator []如果不存在的話會創建一個新的元素,

有時這可能會非常便利,但是最好不要在一個循環中多次使用operator [],如果你不想創建新元素的話。

這也就是當引用一個map作爲一個函數的const型參數的時候不能使用operator []的原因。





********************************************************************************************************************************

STL algorithm

********************************************************************************************************************************

#include <algorithm>



min(a,b), max(a,b), swap(a,b)

find(begin, end, element) 返回iterator第一次出現的地方,沒找到返回end

count(begin, end, element) 返回element出現的次數

set 和 map 都有成員方法 find() 和 count(),時間複雜度爲O(log N), 而std::find() 和 std::count() 爲 O(N). 



介紹兩個有用的算法,可以用在排列組合等等問題

next_permutation(begin, end) 把第一項做爲最高位依次遞減,從當前序列值開始增值到最大,最後設回最小值的一個排列

prev_permutation(begin, end) 類似next_permutation,不過是遞減,而不是遞增,最後設爲最大值

示例:

// int data[3] = { 1, 2, 3}; vector<int> v(data,data+3);

*  1 *  2 *  3     

// do {} while(next_permutation(v.begin(), v.end())); 

1 2 3              

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

*  1 *  2 *  3 // 重設v爲{1, 2, 3},無視v的初始值

// reverse(v.begin(),v.end()); 重設v爲 3 2 1,以執行prev_permutation

// do {} while(prev_permutation(v.begin(), v.end()));

3 2 1

3 1 2

2 3 1

2 1 3

1 3 2

1 2 3

*  3 *  2 *  1 





********************************************************************************************************************************

String Streams

********************************************************************************************************************************

#include <sstream>



編程中經常要對字符串進行處理/輸入/輸出

C++提供了兩個有意思的類 'istringstream' 和 'ostringstream'。

istringstream對象允許你象從標準輸入(stdin)一樣讀取一個字符串,示例代碼:

vector<int> f(const string& s) 

{

    // Construct an object to parse strings 

    istringstream is(s); 

    

    // Vector to store data 

    vector<int> v; 

    

    // Read integer while possible and add it to the vector 

    int tmp; 

    while(is >> tmp) { 

        v.push_back(tmp); 

    } 

    return v;

} 

ostringstream對象用來格式化輸出,示例代碼:

string U(const vector<int>& v) 

{ 

    // Constucvt an object to do formatted output 

    ostringstream os; 

    

    // Copy all elements from vector<int> to string stream as text 

    for (vector<int>::const_iterator it = v.begin(); it != v.end(); it++)

    { 

        os << ' ' << *it; 

    } 



    // Get string from string stream 

    string s = os.str(); 

    

    // Remove first space character 

    if(!s.empty()) { // Beware of empty string here 

        s = s.substr(1); 

    } 

    

    return s; 

} 



********************************************************************************************************************************

總結 summary

********************************************************************************************************************************

這些宏是有作用的,可參考

typedef vector<int> vi; 

typedef vector<vi> vvi; 

typedef pair<int,int> ii; 

#define sz(a) int((a).size()) 

#define pb push_back 

#define all(c) (c).begin(),(c).end() 

// 這個宏vc下不可用,typeof是glibc下定義的

#define tr(c,i) for(typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

#define present(c,x) ((c).find(x) != (c).end()) 

#define cpresent(c,x) (find(all(c),x) != (c).end()) 

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