【STL标准库 & 范型编程】学习笔记(1):C++学习网站、STL六大部件介绍

81 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 11 天,点击查看活动详情

C++学习网站

cplusplus:

在这里插入图片描述

cppreference:

在这里插入图片描述 gcc and gnu: 在这里插入图片描述

STL六大部件

  • 容器(contaubers)
  • 分配器(allocators)
  • 算法(algorithms)
  • 迭代器(iterators)
  • 适配器(adapters):用来修饰(转换)容器、仿函数、迭代器的东西
  • 仿函数(functors):仿函数其行为像函数的东西,所以叫仿

各部件对应关系: 在这里插入图片描述

举例:

#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);
    // 统计ia中元素大于等于40的个数
    cout << count_if(vi.begin(), vi.end(), not1(bind2nd(less<int>(), 40)));
    return 0;
}

// 输出
4

其中:

  • vector:容器container
  • allocator<int> :分配器
  • vi.begin():迭代器
  • count_if:算法
  • bind2nednot1:(访函数)适配器
  • less:仿函数

学习来源

侯捷老师:STL标准库 & 范型编程

容器结构与分类

主要还是分为两类:

  • sequence containers:array、vector、deque、list、forward_list
  • associative containers:set/multiset、map/multimap、unordered set/multiset 、 unordered map/multimap

老师课程上觉得分两类就可以了

测试array

目的:使用array存储500000L个随机数,再进行sort,再利用二分查找查找用户输入的一个数,统计各步骤需要的时间

// 代码来源:课程文件
using namespace std;
const long ASIZE = 500000L;

//----------------------------------------------------
#include <iostream>
#include <cstdio>  //snprintf()
#include <cstdlib> //RAND_MAX
#include <cstring> //strlen(), memcpy()
#include <string>
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);
    return string(buf);
}

int compareLongs(const void *a, const void *b)
{
    return (*(long *)a - *(long *)b);
}

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

//----------------------------------------------------

#include <array>
#include <iostream>
#include <ctime>
#include <cstdlib> //qsort, bsearch, NULL

namespace jj01
{
    void test_array()
    {
        cout << "\ntest_array().......... \n";

        array<long, ASIZE> c;

        clock_t timeStart = clock();
        for (long i = 0; i < ASIZE; ++i)
        {
            c[i] = rand();
        }
        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;

        long target = get_a_target_long();

        timeStart = clock();
        ::qsort(c.data(), ASIZE, sizeof(long), compareLongs);
        long *pItem = (long *)::bsearch(&target, (c.data()), ASIZE, sizeof(long), compareLongs);
        cout << "qsort()+bsearch(), milli-seconds : " << (clock() - timeStart) << endl; //
        if (pItem != NULL)
            cout << "found, " << *pItem << endl;
        else
            cout << "not found! " << endl;
    }
}


//---------------------------------------------------
#include <cstdlib> //rand() and RAND_MAX
int main(int argc, char** argv) 
{
	jj01::test_array();		
		
	return 0;
}

运行结果:

在这里插入图片描述

qsort:基于所指数组进行排序

在这里插入图片描述

bsearch:二分查找

  • void *bsearch(const void *key, const void *base, size_t nelem, size_t width, int(*fcmp)(const void *, const void *));

clock_t的单位是毫秒(milli-seconds)

测试vector

目的:给定一个value,使用vector创建value个随机数,其中转化为string存储于vector中,并比较顺序查找与二分查找的速度差异

using namespace std;
const long ASIZE = 500000L;

//----------------------------------------------------
#include <iostream>
#include <cstdio>  //snprintf()
#include <cstdlib> //RAND_MAX
#include <cstring> //strlen(), memcpy()
#include <string>
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);
    return string(buf);
}

int compareLongs(const void *a, const void *b)
{
    return (*(long *)a - *(long *)b);
}

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

//---------------------------------------------------
#include <vector>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio>  //snprintf()
#include <iostream>
#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 << "vector.max_size()= " << c.max_size() << endl; // 1073747823
        cout << "vector.size()= " << c.size() << endl;
        cout << "vector.front()= " << c.front() << endl;
        cout << "vector.back()= " << c.back() << endl;
        cout << "vector.data()= " << c.data() << endl;
        cout << "vector.capacity()= " << c.capacity() << endl
             << endl;

        string target = get_a_target_string();
        {
            timeStart = clock();
            auto pItem = find(c.begin(), c.end(), target);
            cout << "std::find(), milli-seconds : " << (clock() - timeStart) << endl;

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

        {
            timeStart = clock();
            sort(c.begin(), c.end());
            cout << "sort(), milli-seconds : " << (clock() - timeStart) << endl;

            timeStart = clock();
            string *pItem = (string *)::bsearch(&target, (c.data()),
                                                c.size(), sizeof(string), compareStrings);
            cout << "bsearch(), milli-seconds : " << (clock() - timeStart) << endl;

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

        c.clear();
        // test_moveable(vector<MyString>(), vector<MyStrNoMove>(), value);
    }
}

//---------------------------------------------------
#include <cstdlib> //rand() and RAND_MAX
int main(int argc, char **argv)
{
    long value = 10000;
    jj02::test_vector(value);

    return 0;
}

运行结果:

在这里插入图片描述

Note:

  • snprintf(buf, 10, "%d", rand()); // 将随机数转换string存入buf
  • ::find() // 若在当前namespace没有查找到find函数,则在全局进行查找,::就是进行全局查找
  • capacity()// 获取vector实际开辟的内存空间大小
  • 测试用例的编写:每个测试用例位于一个独立的命名空间
  • vector内存空间扩展方式:放第一个元素,开辟1个内存,当放第二个,开辟2个;当放第三个,开辟4个....
  • abort();// 异常发生后,退出程序

其他

其余容器的测试与array、vector差不多,也就不一一列出

学习来源

侯捷老师:STL标准库 & 范型编程