STL(C++第四次实验)

1、STL:

1.1 STL的概念

STL 是“Standard Template Library”的缩写,中文译为“标准模板库”。STL 是 C++ 标准库的一部分,不用单独安装。
C++ 对模板(Template)支持得很好,STL 就是借助模板把常用的数据结构及其算法都实现了一遍,并且做到了数据结构和算法的分离。例如,vector 的底层为顺序表(数组),list 的底层为双向链表,deque 的底层为循环队列,set 的底层为红黑树,hash_set 的底层为哈希表。

C++ 标准模板库的核心包括以下三个组件:
在这里插入图片描述
这三个组件都带有丰富的预定义函数,帮助我们通过简单的方式处理复杂的任务。

2、实验内容

2.1 结合容器和迭代器实现序列变换

2.1.1 取反


//对数组取反的函数模板
template <typename T>
void transInvT(T a[], T b[], int nNum)
{
    for (int i = 0; i < nNum; i++)
    {
        b[i] = -a[i];
    }
}

2.1.2 平方和立方

template<typename T>
T SqrT(T a)
{
    return a*a;
}
template<typename T>
T InvT(T a)
{
    return -a;
}

2.1.3 完整代码

新建文件cstl.h 、cstl.cpp和main.cpp

cstl.h:

#ifndef CMATRIX_H
#define CMATRIX_H
#include <iostream>
void TestSet();
void Test();
void TestMap();
void TestVector();
#endif#pragma once

cstl.cpp:

#include "cstl.h"
#include <vector>
#include <map>
#include <iostream>
#include <algorithm>
#include <functional>
#include <set>
using namespace std;
//对数组取反的函数模板
template <typename T>
void transInvT(T a[], T b[], int nNum)
{
    for (int i = 0; i < nNum; i++)
    {
        b[i] = -a[i];
    }
}
//遍历数组的函数模板
template < typename T>
void outputCont(string strNme, ostream& os, T begin, T end)
{
    os << strNme + "的结果为:[";
    for (; begin != end; begin++)
    {
        os << *begin << " ";
    }
    os << "]" << endl;
}

template<typename T>
T SqrT(T a)
{
    return a * a;
}
template<typename T>
T LiT(T a)
{
    return a * a * a;
}
template<typename T>
T InvT(T a)
{
    return -a;
}
template<typename inputIter, typename outputIter, typename MyOperator>
void transInvT(inputIter begInput, inputIter endInput,
    outputIter begOutput, MyOperator op)
{
    for (; begInput != endInput; begInput++, begOutput++)
    {
        *begOutput = op(*begInput);
    }
}
void Test()
{
    const int N = 5;
    int a[N] = { 1,2,4,3,5 };
    //遍历数组
    outputCont("a", cout, a, a + N);
    //临时数组(存放数组a经过不同操作后的值)
    int b[N];
    //Vector(向量)是一个封装了动态大小数组的顺序容器(Sequence Container),跟任意其它类型容器一样,
    //它能够存放各种类型的数据。可以简单的认为,向量是一个能够存放任意类型的动态数组
    vector<double> vb(N);
    vector<double> vc(N);
    //对数组元素取反(使用模板)
    transInvT(a, b, N);
    outputCont("取反", cout, b, b + N);
    transInvT(a, a + N, vb.begin(), SqrT<int>);
    outputCont("平方", cout, vb.begin(), vb.end());
    transInvT(a, a + N, vb.begin(), LiT<int>);
    outputCont("立方", cout, vb.begin(), vb.end());
}
Vector(向量)是一个封装了动态大小数组的顺序容器(Sequence Container),跟任意其它类型容器一样,
它能够存放各种类型的数据。可以简单的认为,向量是一个能够存放任意类型的动态数组

main.cpp:

#include "cstl.h"
int main() {
    Test();
    return 0;
}

运行结果:
在这里插入图片描述

2.2 像素变换(二值化)

向cstl.cpp中添加像素变化的函数

template<typename T>
class MyThreshold{
public:
    //带参构造函数,后面的则是初始化,这样的初始化方式效率比较高   
    MyThreshold(int n=128):_nThreshold(n){}
    int operator()(T val)
    {
        return val<_nThreshold?0:1;
    }
    int _nThreshold;
};

Test()函数中添加

    transInvT(a,a+N,vb.begin(),MyThreshold<int>(2));
    outputCont("Inv a by treshold",cout,vb.begin(),vb.end());

此段代码的意思是将像素值小于128(初始设为128,后面可根据调用该函数的实参进行取值)的像素值置0,大于128的像素值置1。

运行结果:
在这里插入图片描述

2.3 使用Set实现学生信息的增删改查

代码:

#include "cstl.h"
#include <vector>
#include <map>
#include <iostream>
#include <algorithm>
#include <functional>
#include <set>
using namespace std;
class studentInfo {
public:
    studentInfo(string strNo, string strName) {
        _strNo = strNo;
        _strName = strName;
    }
    string _strNo;
    string _strName;
    //输出格式
    friend ostream& operator<<(ostream& os, const studentInfo& info)
    {
        os << info._strNo << " " << info._strName;
        return os;
    }
    //进行比较
    friend bool operator<(const studentInfo& info1, const studentInfo& info2)
    {
        return info1._strNo < info2._strNo;
    }
};
template < typename T>
void outputCont(string strNme, ostream& os, T begin, T end)
{
    os << strNme + "的遍历结果为:[";
    for (; begin != end; begin++)
    {
        os << *begin << " ";
    }
    os << "]" << endl;
}
void Test()
{
    vector<studentInfo> students;
    students.push_back(studentInfo("10021", "Zhang san"));
    students.push_back(studentInfo("10002", "Li si"));
    students.push_back(studentInfo("10003", "Wang wu"));
    students.push_back(studentInfo("10011", "Wang liu"));
    students.push_back(studentInfo("10010", "Wu liu"));
    set<studentInfo> studentSet(students.begin(), students.end());
    outputCont("student set", cout, studentSet.begin(), studentSet.end());
    studentSet.insert(studentInfo("100001", "lei wen hui"));
    outputCont("student set insert", cout, studentSet.begin(), studentSet.end());
    studentSet.erase(studentInfo("10011", "Wang liu"));
    outputCont("student set erased", cout, studentSet.begin(), studentSet.end());
}

运行结果:
在这里插入图片描述

3、输入一个字符串,用map统计每个字符出现的次数并输出字符及对应的次数

代码:

#include "cstl.h"
#include <vector>
#include <map>
#include <iostream>
#include <algorithm>
#include <functional>
#include <set>
using namespace std;

void TestMap()
{
    map<char, int> s;   //用来存储字母出现次数的映射
    char c;				//存储输入字符
    do {
        cin >> c;//输入下一个字符
        if (isalpha(c))//判断是否是字母
        {
            c = tolower(c);//将字母转换为小写
            s[c]++;//将该字母的出现频率加1
        }
    } while (c != '.');//碰到“.”则结束输入
        //输出每个字母出现次数
    for (map<char, int>::iterator iter = s.begin(); iter != s.end(); ++iter)
        cout << iter->first << "" << iter->second << " ";
    cout << endl;
}

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值