STL标准库和泛型编程--学习笔记-- level0:使用标准库

01.认识header、版本、重要资源

C++标准库-- Standard Library

STL标准模版库-- Standard Template Library

标准库以header files形式呈现。

新式headers内的组件封装于namespace"std",旧式headers(带.h)内的组件不封装于namespace"std"。

重要网站(标准库检索):

  1. CPlusPlus.com
  2. CppReference.com
  3. gcc.gnu.org

书籍:《THE C++ STANDARD LIBRARY》《STL源码剖析》

02.STL体系结构基础介绍

STL六大部件(Components):

容器Containers  分配器Allocators  算法Algorithms  迭代器Iterators  适配器Adapters  仿函数Functors / Functor Adapters

e.g.六大部件在程序中的体现:

#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>

using namespace std;

//六大部件在程序中的体现
int main(){
    int ia[6] = {27, 210, 12, 47, 109, 83};
    vector<int, allocator<int>> vi(ia, ia+6);
    //使用了容器,分配器(注:此处可以不声明allocator,源代码有默认使用分配器)

    cout << count_if(vi.begin(), vi.end(), not1(bind2nd(less<int>(), 40)));
    //选用了count_if算法:计算出符合该条件的元素有几个
    //vi.begin()到vi.end()范围,用到了iterator迭代器--泛化指针
    /********************************************/
    //less() -- function object -- 选出小于40的元素
    //bind2nd -- function adapter(bind) -- 绑定第二参数
    //not1 -- function adapter(negator) -- 否定条件:大于等于40
    /********************************************/
    //predicate

    return 0;
}

一些概念:

  1. 复杂度(大O计数法)
  2. “前闭后开”区间
    begin()指向第一个元素,end()指向最后一个元素的下一个位置。(注:容器不一定是连续空间)
    //遍历整个容器:
    Contianer<T> c;
    ...
    Container<T>::iterator ite = c.begin();
    for(; ite != c.end(); ++ite)
    
    //C++11标准
    //range-based for statement
    for( decl : Coll ){
        statement
    }
    //decl--声明; coll--容器collection
    
    //example1--range
    for( int i : {2, 3, 5, 7, 9, 13, 17, 19}){
        std::cout << i << std::end;
    }
    
    std::vector<double> vec;
    ...
    //遍历容器
    for( auto elem : vec ){
        std::cout << elem << std::end;
    }
    
    //此处要用引用才会修改它的值
    for( auto& elem : vec ){
        elem *= 3;
    }
    
    //example2--auto keyword(since C++11)
    list<string> c;
    ...
    list<string>::iterator ite;
    ite = ::find(c.begin(), c.end(), target);
    
    //equal=
    list<string> c;
    ...
    auto ite = ::find(c.begin(), c.end(), target);
    

结构--

选择结构

循环结构

迭代结构(循环特例)

块结构

03.容器之分类

结构与分类

  1. Sequence Containers--序列式容器
            Array(C++11):连续空间,长度固定
            Vector:只有一端能扩充
            Deque:双向队列,前后都能扩充
            List:双向链表
            Forward-List(C++11):单链表
  2. Associative Containers--关联式容器
    底部是用红黑树做的
    Muti--key可以重复
            Set/Multiset--不分key和value
            Map/Multimap--有key有value
  3. Unordered Containers(C++11)--不定序容器(包含于2)

04.容器测试程序

注:声明一个变量时没有缩进

       之前声明过的头文件有所重复但是函数头文件可以重复声明

一些辅助函数​​​​​​​

using std::cin;
using std::cout;
using std::string;

//交互式输入要寻找的目标
long get_a_target_long(){
    long target = 0;
    
    cout << "target (0~" << RAND_MAX << "):";
    cin >> target;
    return target;
}

//写入目标并转换成字符串型
string get_a_target_string(){
    long target = 0;
    char buf[10];

    cout << "target (0~" << RAND_MAX << "):";
    cin >> target;
    snprintf(buf, 10, "%d", target);//将可变个参数按照format格式化成字符串
    return string(buf);
}

//qsort函数--C语言编译器函数库自带的排序函数
//函数原型  void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
//base-- 指向要排序的数组的第一个元素的指针。
//nitems-- 由 base 指向的数组中元素的个数。
//size-- 数组中每个元素的大小,以字节为单位。
//compar-- 用来比较两个元素的函数,即函数指针(回调函数)

//compar函数设置
//1.比较长度
int compareLongs(const void* a, const void* b){
    return ( *(long*)a - *(long*)b );
}

//2.比较字符串大小
int compareStrings(const void* a, const void* b){
    if( *(string*)a > *(string*)b )
        return 1;
    else if( *(string*)a < *(string*)b )
        return -1;
    else
        return 0;
}

使用容器array

#include <array>
#include <iostream>
#include <ctime>
#include <cstdlib> //qsort,bsearch,NULL
namespace jj01
{
void test_array()
{
    //array容器测试
    cout << "\ntest_array().........\n";

array <long,ASIZE> c;//long类型,ASIZE大小,名称取为c

clock_t timeStart = clock();
    //将array放满随机数
    for(long i = 0; i < ASIZE; ++i){
        c[i] = rand();//先得设随机种子--srand
    }
    
    cout << "milli-seconds : " << (clock()-timeStart) << endl;
    
    //array提供的操作函数:
    cout << "array.size()= : " << c.size() << endl;
    cout << "array.front()= : " << c.front() << endl;//array第一个元素
    cout << "array.back()= : " << c.back() << endl;//array尾元素
    cout << "array.data()= : " << c.data() << endl;//array数组在起点处的地址
}

long target = get_a_target_long();

    timeStart = clock();//计时函数:从程序开始运行到当下所花费的毫秒数
    //qsort--对数组排序排序:起始地址,多少元素,每个元素大小,比大小原则
    qsort(c.data(), ASIZE, sizeof(long), compareLongs);
//bsearch -- 二分查找法
long* pItem =(long*)bsearch(&target, (c.data()), ASIZE, sizeof(long),compareLongs);
    cout << "qsort()+bsearch(),milli-seconds:" << (clock()-timeStart) << endl;
    //(clock()-timeStart 是指运行qsort和bsearch消耗的时间
    if(pItem != NULL)
        cout << "found," << *pItem << endl;
    else
        cout << "not found!" << endl;
}
}

使用容器vector

#include <vector>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio> //snprintf()
#include <iosteam>
#include <ctime>
#include <algorithm> //sort()
namespace jj02
{
void test_vector(long& value)
{
    cout << "\ntest_vector().........\n";

vector<string> c;
char buf[10];

clock_t timeStart = clock();
    for(long i = 0; i < value; ++i)
    {
        try{
            snprintf(buf, 10, "%d", rand());
            c.push_back(string(buf));
        }
        catch(exception& p){
            cout << "i=" << i << " " << p.what() << endl;
                //曾经最高 i=58389486 then std::bad_alloc
            abort();
        }
    }
    cout << "milli-seconds : " << (clock()-timeStart) << endl;
    cout << "array.size()= : " << c.size() << endl;
    cout << "array.front()= : " << c.front() << endl;
    cout << "array.back()= : " << c.back() << endl;
    cout << "array.data()= : " << c.data() << endl;
    cout << "array.capacity()= : " << c.capacity() << endl;
string target = get_a_target_string();
    {
    timeStart = clock();
auto pItem = ::find(c.begin(), c.end(), target);
    cout << "::find(), milli-seconds:" << (clock()-timeStart) << endl;

    if(pItem != c.end())
        cout << "found, " << *pItem << endl;
    else
        cout << "not found!" << endl;
    }

    {
    timeStart = clock();
    sort(c.begin(),c.end());
string* pItem = (string*)bsearch(&target, (c.data()),
                                 c.size, sizeof(string), compareString);

    cout << "sort()+bsearch(),milli-seconds:" << (clock()-timeStart) << endl;
    //运行sort和bsearch消耗的时间

    if(pItem != NULL)
        cout << "found," << *pItem << endl;
    else
        cout << "not found!" << endl;
    }

}
}

......

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值