目录
实验要求
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
需要注意的是
-
需要导入头文件
#include <map> // STL头文件没有扩展名.h
- 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;
}
运行结果