学习C++面向对象已经有过去半个学期,从基础已经学到了STL模板的运用。现将STL知识点以及操作汇总总结如下:
STL由一些可适应不同需求的集合类(collection class),以及在这些数据集合上操作的算法(algorithm)构成。其所有的组件都由模板构成,其元素可以是任意类型。
注意:
所有容器存放的都是值而非引用
STL容器元素的条件
必须能够通过拷贝构造函数进行复制
必须可以通过赋值运算符完成赋值操作
必须可以通过析构函数完称销毁动作
序列式容器元素的默认构造函数必须可用
某些动作必须定义operator ==,例如搜寻操作
关联式容器必须定义出排序准则,默认情况是重载
大小:
size()
empty()
max_size()
比较:
==,!=,<,<=,>,>=
==注意:==比较操作两端的容器必须属于同一类型;如果两个容器内的所有元素按序相等,那么这两个容器相等;采用字典式顺序判断某个容器是否小于另一个容器。
赋值(assignment)和交换(swap)
与迭代器(iterator)相关的操作
begin()
end()
rbegin()
rend()
元素操作
insert(pos,e)-将元素e的拷贝安插于迭代器pos所指的位置
erase(beg,end)-移除[beg,end]区间内的所有元素
clear()-移除所有元素
迭代器可遍历STL容器内全部或部分元素的对象
指出容器中的一个特定位置
迭代器的基本函数:
半开区间[beg, end)的好处:
1.为遍历元素时循环的结束时机提供了简单的判断依据(只要未到达end(),循环就可以继续)
2.不必对空区间采取特殊处理(空区间的begin()就等于end())
迭代器的分类
双向迭代器(list set map 提供双向迭代器)
随机存储迭代器(vector deque string提供了随即存放迭代器)
vector模拟动态数组,支持随机存取
必须包含的头文件
#include
vector的大小(size)和容量(capacity)
size返回实际元素个数
capacity返回vector能容纳的元素最大数量。
std::list<T> l;
std::vector<T> v;
…
v.assign(l.begin(),l.end());
std::vector<T> v;//empty
v[5]= t; //runtime error
std::cout << v.front(); //runtime error
vector实例操作代码:
#include
int main(){
vector<int> a;
for (int i = 0; i < 5; ++i){
a.push_back(5 - i);
}
cout << a.size() << endl;
a.pop_back();
a[0] = 1;
cout << a.size() << endl;
for (int i = 0; i < (int)a.size(); ++i){
cout << a[i] << ", " << endl;
}
cout << endl;
sort(a.begin(), a.end());
cout << "Size: " << a.size() << endl;
for (int i = 0; i < (int)a.size(); ++i){
cout << a[i] << ", " << endl;
}
cout << endl;
a.clear();
cout << "Size: " << a.size() << endl;
return 0;
}
使用二叉树管理元素
元素包含两部分(key,value),key和value可以是任意类型
必须包含的头文件
#include
注意: map和multimap
map中不允许key相同的元素,multimap允许key相同的元素
map操作实例
struct T1{
int v;
bool operator<(const T1 &a)const{
return (v < a.v);
}
};
struct T2{
int v;
};
struct cmp{
const bool operator()(const T2 &a, const T2 &b){
return (a.v < b.v);
}
};
int main(){
map<T1, int>mt1; //example for user-defined class
map<T2, int, cmp>mt2; //example for user-defined class(functor)
map<string, int> m2;
map<string, int>::iterator m2i, p1, p2;
m2["abd"] = 2;
m2["abc"] = 1;
m2["cba"] = 2;
m2.insert(make_pair("aaa", 9));
m2["abf"] = 4;
m2["abe"] = 2;
cout << m2["abc"] << endl;
m2i = m2.find("cba");
if(m2i != m2.end()){
cout << m2i->first << ": " << m2i->second << endl;
}else{
cout << "find nothing" << endl;
}
cout << "Iterate" << endl;
for(m2i = m2.begin(); m2i != m2.end(); m2i++){
cout << m2i->first << ": " << m2i->second << endl;
}
}
multimap操作实例
multimap<string, int> mm1;
multimap<string, int>::iterator mm1i, p1, p2;
mm1.insert(make_pair("b", 3));
mm1.insert(make_pair("a", 0));
mm1.insert(make_pair("b", 5));
mm1.insert(make_pair("c", 4));
mm1.insert(make_pair("b", 2));
cout << mm1.size() << endl;
for(mm1i = mm1.begin(); mm1i != mm1.end(); mm1i++){
cout << mm1i->first << ": " << mm1i->second << endl;
}
cout << "COUNT: " << mm1.count("b") << endl;
cout << "Bound: " << endl;
p1 = mm1.lower_bound("b");
p2 = mm1.upper_bound("b");
for(mm1i = p1; mm1i != p2; mm1i++){
cout << mm1i->first << ": " << mm1i->second << endl;
}
使用平衡二叉树管理元素
集合set
是一种已排序对象的关联容器
必须包含头文件
#include
set操作实例
struct T1{
int key;
int value1, value2;
bool operator<(const T1 &b)const{
return (key < b.key);
}
};
struct T2{
int key;
int v1, v2;
};
struct T2cmp{
bool operator()(const T2 &a, const T2 &b){
return (a.key < b.key);
}
};
int main(){
set<T1> s2;
set<T2, T2cmp> s3;
#if 1
set<string>s1;
set<string>::iterator iter1;
#else
set<string, greater<string> >s1;
set<string, greater<string> >::iterator iter1;
#endif
s1.insert("abc");
s1.insert("abc");
s1.insert("abc");
s1.insert("bca");
s1.insert("aaa");
cout << "ITERATE:" << endl;
for (iter1 = s1.begin(); iter1 != s1.end(); iter1++){
cout << (*iter1) << endl;
}
cout << "FIND:" << endl;
iter1 = s1.find("abc");
if(iter1 != s1.end()) {
cout << *iter1 << endl;
}else{
cout << "NOT FOUND" << endl;
}
return 0;
}
multiset操作实例
int main(){
multiset<T1> s2;
multiset<T2, T2cmp> s3;
#if 1
multiset<string>s1;
multiset<string>::iterator iter1;
#else
multiset<string, greater<string> >s1;
multiset<string, greater<string> >::iterator iter1;
#endif
s1.insert("abc");
s1.insert("abc");
s1.insert("abc");
s1.insert("bca");
s1.insert("aaa");
cout << "ITERATE:" << endl;
for (iter1 = s1.begin(); iter1 != s1.end(); iter1++)
cout << (*iter1) << endl;
cout << "FIND:" << endl;
iter1 = s1.find("abc");
if(iter1 != s1.end())
cout << *iter1 << endl;
else cout << "NOT FOUND" << endl;
cout << s1.count("abc") << endl;
multiset<string>::iterator s1i, p1, p2;
p1 = s1.lower_bound("abc");
p2 = s1.upper_bound("abc");
for(s1i = p1; s1i != p2; s1i++){
cout << (*s1i) << endl;
}
return 0;
}
pair 模板:
pair模板可以用于生成 key-value对
注意:
所有算法的前两个参数都是一对iterators:[first,last),用来指出容器内一个范围内的元素。
每个算法的声明中,都表现出它所需要的最低层次的iterator类型。
以下举例主要的算法函数:
class CLessThen9 {
public:
bool operator()( int n) { return n < 9; }
};
void outputSquare(int value ) { cout << value * value << " "; }
}
int main() {
const int SIZE = 10;
int a1[] = { 100,2,8,1,50,3,8,9,10,2 };
vector<int> v(a1,a1+SIZE);
ostream_iterator<int> output(cout," ");
cout << endl << "2)";
cout << count(v.begin(),v.end(),8);
cout << endl << "3)";
cout << count_if(v.begin(),v.end(),CLessThen9());
cout << endl << "4)";
cout << * (min_element(v.begin(),v.end()));
cout << endl << "5)";
cout << * (max_element(v.begin(),v.end()));
cout << endl << "7) ";
for_each(v.begin(),v.end(),outputSquare);
结果:
2)2
3)6
4)1
5)100
7) 10000 4 64 1 2500 9 64 81 100 4
排序和查找
实例
bool Greater10(int n)
{
return n > 10;
}
main() {
const int SIZE = 10;
int a1[] = { 2,8,1,50,3,100,8,9,10,2 };
vector<int> v(a1,a1+SIZE);
ostream_iterator<int> output(cout," ");
vector<int>::iterator location;
location = find(v.begin(),v.end(),10);
if( location != v.end()) {
cout << endl << "1) " << location - v.begin();
}
location = find_if( v.begin(),v.end(),Greater10);
if( location != v.end())
cout << endl << "2) " << location - v.begin();
sort(v.begin(),v.end());
if( binary_search(v.begin(),v.end(),9)) {
cout << endl << "3) " << "9 found";
}
}
结果:
1)8
2) 3
3)9 found
改变序列的排序
有很多时候怀疑了自己,我真的不知道别人哪里来的动力拼了命的学习,而自己就会讨厌自己,怀疑自己。我总结,我反思,思考出来很多道理,着手去做的时候信心满满,可往往以不理想的结果去收场。在家里事情太多了,很乱就很烦躁。这学期时间已经过去一半了,可距离自己学期初顶定下的目标,越来越远,越来越远。很想回学校,也很想出去透透气。生活还得继续,每次就这样给自己加油打气。
关于C++:
1、文件读写操作,因为在Java中学过,但也基本上忘干净了,就是要不断的写代码,写代码。
2、STL的作业很让我头大,代码地基要打好,否则牵一发而动全身,错错错,小菜的感悟。
3、通过这次的作业,也让我看到了自己的太多不足,心态不要崩,代码要多练。
4、码代码速度太慢,速度跟不上想象还,不是想的快,是码的慢。
5、转专业后悔了吗?没有,还得继续调整,继续努力,未来是自己的,奋斗十年,趁年轻,加油!