C++实验(四)——STL学习

目录

实验要求

概述

代码练习

1.序列变换(如取反、平方、立方)

2.像素变换(二值化、灰度拉伸)

3.用set存储学生信息,并进行增删改查操作

添加函数

删除函数

set查找和统计

4.用map统计每个字符出现的次数(输出字符及对应的次数)


实验要求

1.撰写自己的算法和函数,结合容器和迭代器解决序列变换(如取反、平方、立方),像素变换(二值化、灰度拉伸);

2.用set存储学生信息,并进行增删改查操作;

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

概述

STL六大组件简介
STL提供了六大组件,彼此之间可以组合套用,这六大组件分别是:容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器。

容器:各种数据结构,如vector、list、deque、set、map等,用来存放数据,从实现角度来看,STL容器是一种class template。

算法:各种常用的算法,如sort、find、copy、for_each。从实现的角度来看,STL算法是一种function tempalte.

迭代器:扮演了容器与算法之间的胶合剂,共有五种类型,从实现角度来看,迭代器是一种将operator* , operator-> , operator++,operator–等指针相关操作予以重载的class template. 所有STL容器都附带有自己专属的迭代器,只有容器的设计者才知道如何遍历自己的元素。原生指针(native pointer)也是一种迭代器。

仿函数:行为类似函数,可作为算法的某种策略。从实现角度来看,仿函数是一种重载了operator()的class 或者class template

适配器:一种用来修饰容器或者仿函数或迭代器接口的东西。

空间配置器:负责空间的配置与管理。从实现角度看,配置器是一个实现了动态空间配置、空间管理、空间释放的class tempalte.

STL六大组件的交互关系,容器通过空间配置器取得数据存储空间,算法通过迭代器存储容器中的内容,仿函数可以协助算法完成不同的策略的变化,适配器可以修饰仿函数
 

代码练习

1.序列变换(如取反、平方、立方)

//1、取反操作
void transInv(int a[],int b[],int num){
    for(int i=0;i<num;i++)
    {
        b[i]=-a[i];
    }
}
//2、平方操作
void transSqr(int a[],int b[],int num)
{
    for(int i=0;i<num;i++)
    {
        b[i]=a[i]*a[i];
    }
}
//3、立方操作
void transCubic(int a[],int b[],int num)
{
    for(int i=0;i<num;i++)
    {
        b[i]=a[i]*a[i]*a[i];
    }
}
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);
    }
}

//对结果进行输出
template <typename T>
void outputCont(string strName,ostream &os,T begin,T end)
{
    os<<strName<<":";
    for(;begin!=end;begin++)
    {
        os<<*begin<<"\t";
    }
    os<<endl;
}


//同理 模板函数
template <typename T>
void transInvT(T a[],T b[],int num)
{
    for(int i=0;i<num;i++)
    {
        b[i]=-a[i];
    }
}
template <typename T>
void transSqrT(T a[],T b[],int num)
{
    for(int i=0;i<num;i++)
    {
        b[i]=a[i]*a[i];
    }
}
template <typename T>
void transCubicT(T a[],T b[],int num)
{
    for(int i=0;i<num;i++)
    {
        b[i]=a[i]*a[i]*a[i];
    }
}

2.像素变换(二值化、灰度拉伸)

//图像二值化
template <typename T>
class Mythreshold
{
public:
    Mythreshold(int n=128):_nThreshold(n){}
    int operator()(T val)
    {
        return val<_nThreshold?0:1;
    }
    int _nThreshold;
};

3.用set存储学生信息,并进行增删改查操作

Set的特性是所有元素都会根据元素的键值自动被排序。Set的元素不像map那样可以同时拥有实值和键值,Set的元素即是键值又是实值。同时Set不允许两个元素有相同的键值

我们对Set做个简单测试

TestSet 

void printSet(set<int> & s)
{
    for (set<int>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

//构造和赋值
void test01()
{
    set<int> s1;
    s1.insert(10);
    s1.insert(30);
    s1.insert(20);
    s1.insert(40);
    printSet(s1);
    //拷贝构造
    set<int>s2(s1);
    printSet(s2);
    //赋值
    set<int>s3;
    s3 = s2;
    printSet(s3);
}

运行结果

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

Set中的函数

添加函数

  • 在容器中插入元素:st.insert(const T& x);
  • 任意位置插入一个元素:st.insert(iterator it, const T& x);

删除函数

  • 删除容器中值为 elem 的元素:st.pop_back(const T& elem);
  • 删除it迭代器所指的元素:st.erase(iterator it);
  • 删除区间 [first,last] 之间的所有元素:st.erase(iterator first, iterator last);
  • 清空所有元素:st.clear();

set查找和统计

  • find(key); //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
  • count(key); //统计key的元素个数
    cout << "Hello World!" << endl;

        vector<studentInfo> students;
        students.push_back(studentInfo("01", "A"));
        students.push_back(studentInfo("02", "B"));
        students.push_back(studentInfo("03", "C"));
        students.push_back(studentInfo("04", "D"));
        students.push_back(studentInfo("05", "E"));
        set<studentInfo> studentSet(students.begin(), students.end());

        //输出Set中所有的元素
        outputCont("studentInfo ", cout, studentSet.begin(), studentSet.end());
        //插入(增)
        studentSet.insert(studentInfo("07", "Xu"));
        outputCont("insert ", cout, studentSet.begin(), studentSet.end());

        //删除
        studentSet.erase(studentInfo("01", "A"));
        outputCont("erase ", cout, studentSet.begin(), studentSet.end());

        //值得注意的是 不能通过 set 的迭代器去修改 set 元素,原因是修改元素会破坏 set 组织。
        //查
        if (studentSet.find(studentInfo("05", "E")) != studentSet.end())
        {
            cout << "yes!" << endl;
        }
        else
        {
            cout << "no!" << endl;
        }

        return 0;

运行结果

4.用map统计每个字符出现的次数(输出字符及对应的次数)

map是STL的一个关联容器,它提供一对一的hash。

  • 第一个可以称为关键字(key),每个关键字只能在map中出现一次;
  • 第二个可能称为该关键字的值(value);

就如下图所示 每个key都有与之对应的value

需要注意的是

  1. 需要导入头文件

    #include <map> // STL头文件没有扩展名.h
  2. map 对象是一个模版类,需要关键字和存储对象两个模版参数
     std::map<int , std::string> person;
     begin()         返回指向map头部的迭代器

     clear()        删除所有元素

     count()         返回指定元素出现的次数, (帮助评论区理解: 因为key值不会重复,所以只能是1 or 0)

     empty()         如果map为空则返回true

     end()           返回指向map末尾的迭代器

     equal_range()   返回特殊条目的迭代器对

     erase()         删除一个元素

     find()          查找一个元素

     get_allocator() 返回map的配置器

     insert()        插入元素

     key_comp()      返回比较元素key的函数

     lower_bound()   返回键值>=给定元素的第一个位置

     max_size()      返回可以容纳的最大元素个数

     rbegin()        返回一个指向map尾部的逆向迭代器

     rend()          返回一个指向map头部的逆向迭代器

     size()          返回map中元素的个数

     swap()           交换两个map

     upper_bound()    返回键值>给定元素的第一个位置

     value_comp()     返回比较元素value的函数

代码

#include <iostream>
#include <map>
#include <cctype>
using namespace std;
int main() {
    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;
    return 0;
}

运行结果

 (31条消息) C++提高编程(三)_Augenstern_QXL的博客-CSDN博客icon-default.png?t=LA92https://blog.csdn.net/Augenstern_QXL/article/details/117253848

猜你喜欢

转载自blog.csdn.net/m0_50945459/article/details/121583415