C++ STL模板
C++中的STL(Standard Template Library)用起来挺方便的,这里我们来做一下总结。
一、set
set是STL中一种标准关联容器 (vector,list,string,deque都是序列容器,而set,multiset,map,multimap是标准关联容器),它底层使用 平衡的搜索树——红黑树实现,插入删除操作时仅仅需要指针操作节点即可完成,不涉及到内存移动和拷贝,所以效率比较高。
在set中元素都是唯一的,而且默认情况下会对元素 自动进行升序排列,支持集合的交(set_intersection),差(set_difference) 并(set_union),对称差(set_symmetric_difference) 等一些集合上的操作,如果需要集合中的元素允许重复那么可以使用multiset。
1)插入(insert)
set的元素添加时使用insert()方法,示例如下:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main(){ 5 set<int>s; 6 int n; 7 cout << "input: "; 8 for(int i = 0; i < 5; i++){ 9 cin >> n; 10 s.insert(n); 11 } 12 cout << "output: "; 13 for(set<int>::iterator it = s.begin(); it != s.end(); ++it){ 14 cout << *it << ' '; 15 } 16 }
运行结果如下:
可见set已为我们剔除了相同的元素了,并且默认升序输出。假如我们想构造一个升序的set,可以这样声明:set<int, greater<int>> s ;
2)历遍
set的历遍一般是用迭代器iterator,这是对指针的封装,示例代码如上。
3)初始化
我们可以使用数组来进行初始化,或者用复制构造函数:
1 int main(){ 2 int A[3] = {1, 2, 3}; 3 set<int> setA(A, A + 3); 4 set<int> setB(setA); 5 }
4)并集、交集、差集
利用set的方法可以方便地求出并集、交集和差集:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main(){ 5 int A[3] = {1, 2, 3}; 6 int B[4] = {1, 2, 4, -1}; 7 set<int> setA(A, A + 3); 8 set<int> setB(B, B + 4); 9 set<int> set1, set2, set3; 10 11 set_union(setA.begin(), setA.end(), setB.begin(), setB.end(), insert_iterator<set<int>>(set1, set1.begin())); 12 set_intersection(setA.begin(), setA.end(), setB.begin(), setB.end(), insert_iterator<set<int>>(set2, set2.begin())); 13 set_difference(setA.begin(), setA.end(), setB.begin(), setB.end(), insert_iterator<set<int>>(set3, set3.begin())); 14 15 cout << "union: "; 16 for(set<int>::iterator it = set1.begin(); it != set1.end(); ++it) cout << *it << ' '; cout << endl; 17 18 cout << "intersection: "; 19 for(set<int>::iterator it = set2.begin(); it != set2.end(); ++it) cout << *it << ' '; cout << endl; 20 21 cout << "difference: "; 22 for(set<int>::iterator it = set3.begin(); it != set3.end(); ++it) cout << *it << ' '; cout << endl; 23 }
三个函数的参数都类似,运行效果如下:
二、map
map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能 力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一种非严 格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的。
1)声明
1 map<string, int> m1; 2 map<int, string> m2; 3 map<string, char> m3; 4 map< char, string> m4; 5 map<char, int> m5; 6 map<int, char> m6;
以上我们分别声明了6个不同的映射。
2)插入
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main(){ 5 map<string, string> m; 6 7 m.insert(make_pair("A", "apple")); 8 m.insert(pair<string, string>("B", "banana")); 9 m.insert(map<string, string>::value_type("C", "cherry")); 10 }
以上我们分别用了三种方式进行元素的插入,其效果都是一样的。当然还有另一种简单的方式如:m["A"] = "apple"。这种方式有所不同:一般的话,后面的方式可以修改前面的方式的值,反之不能。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main(){ 5 map<string, string> m; 6 //m["A"] = "foo"; 7 m.insert(make_pair("A", "apple")); 8 m.insert(pair<string, string>("B", "banana")); 9 m.insert(map<string, string>::value_type("C", "cherry")); 10 m["A"] = "boo"; 11 12 cout << m["A"] << endl; 13 cout << m["B"] << endl; 14 cout << m["C"] << endl; 15 }
上面我们用m["A"] = "boo" 来修改原来的映射,运行结果如下:
可见修改成功。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main(){ 5 map<string, string> m; 6 m["A"] = "foo"; 7 m.insert(make_pair("A", "apple")); 8 m.insert(pair<string, string>("B", "banana")); 9 m.insert(map<string, string>::value_type("C", "cherry")); 10 //m["A"] = "boo"; 11 12 cout << m["A"] << endl; 13 cout << m["B"] << endl; 14 cout << m["C"] << endl; 15 }
现在我们用make_pair试图进行修改,结果如下:
可见,修改失败。
3)历遍
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main(){ 5 map<string, string> m; 6 7 m.insert(make_pair("A", "apple")); 8 m.insert(pair<string, string>("B", "banana")); 9 m.insert(map<string, string>::value_type("C", "cherry")); 10 11 for(map<string, string>::iterator it = m.begin(); it != m.end(); ++it){ 12 cout << it->first << ' ' << it->second << endl; 13 } 14 15 cout << m["A"] << endl; 16 cout << m["B"] << endl; 17 cout << m["C"] << endl; 18 19 }
我们可以使用map的迭代器进行历遍,分别输出first和second,也可以像使用数组一样对map进行访问,运行结果如下:
4)删除
在刚在的代码中,我们需要删除元素,可以这么做:
1 map<string, string>::iterator it; 2 it = m.find("A"); 3 m.erase(it);
5)查找
假如我们想要知道一个映射是否存在,可以这么做:
1 map<int, char> m; 2 if(m.find(0) == m.end()) cout << "not found" << endl; 3 else cout << "found" << endl;
假若m[0]未被赋值,则m.find(0) == m.end()。
//End