【C++】阶段性总结(二)——STL的操作

学习C++面向对象已经有过去半个学期,从基础已经学到了STL模板的运用。现将STL知识点以及操作汇总总结如下:

C++ Standard Template Libarrary

STL由一些可适应不同需求的集合类(collection class),以及在这些数据集合上操作的算法(algorithm)构成。其所有的组件都由模板构成,其元素可以是任意类型。

STL概述

STL容器
【C++】阶段性总结(二)——STL的操作_第1张图片

【C++】阶段性总结(二)——STL的操作_第2张图片

注意:

所有容器存放的都是值而非引用

STL容器元素的条件

必须能够通过拷贝构造函数进行复制
必须可以通过赋值运算符完成赋值操作
必须可以通过析构函数完称销毁动作
序列式容器元素的默认构造函数必须可用
某些动作必须定义operator ==,例如搜寻操作
关联式容器必须定义出排序准则,默认情况是重载

STL容器的共同操作

在这里插入图片描述

【C++】阶段性总结(二)——STL的操作_第3张图片

【C++】阶段性总结(二)——STL的操作_第4张图片

  1. 大小:
    size()
    empty()
    max_size()

  2. 比较:
    ==,!=,<,<=,>,>=

==注意:==比较操作两端的容器必须属于同一类型;如果两个容器内的所有元素按序相等,那么这两个容器相等;采用字典式顺序判断某个容器是否小于另一个容器。

  1. 赋值(assignment)和交换(swap)

  2. 与迭代器(iterator)相关的操作
    begin()
    end()
    rbegin()
    rend()

  3. 元素操作

insert(pos,e)-将元素e的拷贝安插于迭代器pos所指的位置
erase(beg,end)-移除[beg,end]区间内的所有元素
clear()-移除所有元素

迭代器(iterator)

迭代器可遍历STL容器内全部或部分元素的对象
指出容器中的一个特定位置

迭代器的基本操作
【C++】阶段性总结(二)——STL的操作_第5张图片

迭代器的基本函数:

【C++】阶段性总结(二)——STL的操作_第6张图片

【C++】阶段性总结(二)——STL的操作_第7张图片

半开区间[beg, end)的好处:

1.为遍历元素时循环的结束时机提供了简单的判断依据(只要未到达end(),循环就可以继续)
2.不必对空区间采取特殊处理(空区间的begin()就等于end())

示例
【C++】阶段性总结(二)——STL的操作_第8张图片

迭代器的分类

双向迭代器(list set map 提供双向迭代器)
随机存储迭代器(vector deque string提供了随即存放迭代器)

vector

vector模拟动态数组,支持随机存取
必须包含的头文件

#include 

vector的大小(size)和容量(capacity)

size返回实际元素个数
capacity返回vector能容纳的元素最大数量。

非变动操作

【C++】阶段性总结(二)——STL的操作_第9张图片

赋值操作

【C++】阶段性总结(二)——STL的操作_第10张图片

std::list<T> l;
 std::vector<T> v;
 …
 v.assign(l.begin(),l.end());

元素存取

【C++】阶段性总结(二)——STL的操作_第11张图片

 std::vector<T> v;//empty
 v[5]= t;   //runtime error
 std::cout << v.front(); //runtime error

迭代器相关函数

【C++】阶段性总结(二)——STL的操作_第12张图片

移除(remove)元素

【C++】阶段性总结(二)——STL的操作_第13张图片

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;
}

map/multimap

使用二叉树管理元素
元素包含两部分(key,value),key和value可以是任意类型
必须包含的头文件

#include 

注意: map和multimap
map中不允许key相同的元素,multimap允许key相同的元素

构造拷贝析构

【C++】阶段性总结(二)——STL的操作_第14张图片

赋值

【C++】阶段性总结(二)——STL的操作_第15张图片

特殊搜寻操作

【C++】阶段性总结(二)——STL的操作_第16张图片

安插(insert)元素

【C++】阶段性总结(二)——STL的操作_第17张图片

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/multiset

使用平衡二叉树管理元素
集合set
是一种已排序对象的关联容器
必须包含头文件

#include

操作

【C++】阶段性总结(二)——STL的操作_第18张图片

【C++】阶段性总结(二)——STL的操作_第19张图片

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对

algorithm

注意:
所有算法的前两个参数都是一对iterators:[first,last),用来指出容器内一个范围内的元素。
每个算法的声明中,都表现出它所需要的最低层次的iterator类型。

以下举例主要的算法函数:

count/count_if

【C++】阶段性总结(二)——STL的操作_第20张图片
【C++】阶段性总结(二)——STL的操作_第21张图片

最小元素/最大元素

【C++】阶段性总结(二)——STL的操作_第22张图片
【C++】阶段性总结(二)——STL的操作_第23张图片

for_each

【C++】阶段性总结(二)——STL的操作_第24张图片
实例

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

排序和查找

find/find_if

【C++】阶段性总结(二)——STL的操作_第25张图片
【C++】阶段性总结(二)——STL的操作_第26张图片

binary_search

lower_bound/uper_bound/equal_bound

实例

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

sort排序

【C++】阶段性总结(二)——STL的操作_第27张图片

改变序列的排序

unique

【C++】阶段性总结(二)——STL的操作_第28张图片

reverse【C++】阶段性总结(二)——STL的操作_第29张图片

体会感悟

有很多时候怀疑了自己,我真的不知道别人哪里来的动力拼了命的学习,而自己就会讨厌自己,怀疑自己。我总结,我反思,思考出来很多道理,着手去做的时候信心满满,可往往以不理想的结果去收场。在家里事情太多了,很乱就很烦躁。这学期时间已经过去一半了,可距离自己学期初顶定下的目标,越来越远,越来越远。很想回学校,也很想出去透透气。生活还得继续,每次就这样给自己加油打气。
关于C++:
1、文件读写操作,因为在Java中学过,但也基本上忘干净了,就是要不断的写代码,写代码。
2、STL的作业很让我头大,代码地基要打好,否则牵一发而动全身,错错错,小菜的感悟。
3、通过这次的作业,也让我看到了自己的太多不足,心态不要崩,代码要多练。
4、码代码速度太慢,速度跟不上想象还,不是想的快,是码的慢。
5、转专业后悔了吗?没有,还得继续调整,继续努力,未来是自己的,奋斗十年,趁年轻,加油!

你可能感兴趣的:(C++作业,c++,stl)