文章目录
1.SLT算法
STL算法本身是一种函数模版
通过迭代器获得输入数据
通过函数对象对数据进行处理
通过迭代器将结果输出
STL算法是通用的,独立于具体的数据类型、容器类型
2.SLT算法分为:
不可变序列算法
可变序列算法
排序和搜索算法
数值算法
3.迭代器:
迭代器是算法和容器的桥梁
迭代器用作访问容器中的元素
算法不直接操作容器中的数据,而是通过迭代器间接操作
算法和容器独立
增加新的算法,无需影响容器的实现
增加新的容器,原有的算法也能适用
一、撰写自己的算法和函数,结合容器和迭代器解决序列变换(如取反、平方、立方),像素变换(二值化、灰度拉伸)
代码如下:
void transInv(int a[],int b[],int nNum) //取反
{
for(int i=0;i<nNum;i++)
{
b[i] = -a[i];
}
}
void transSqr(int a[],int b[],int nNum) //平方
{
for(int i=0;i<nNum;i++)
{
b[i] = a[i]*a[i];
}
}
void transCube(int a[],int b[],int nNum) //立方
{
for(int i=0;i<nNum;i++)
{
b[i] = a[i]*a[i]*a[i];
}
}
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>
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 = ‐ (*begInput);
*begOutPut = op(*begInput);
}
}
template <typename T> //输出
void outputCont(string strNme,ostream& os, T begin, T end)
{
os<<strNme<<":";
for(;begin!=end;begin++)
{
os<<*begin<<"\t";
}
os<<endl;
}
template<typename T>
class MyThreshold{ //图像二值化
public:
MyThreshold(int n=128):_nThreshold(n){}
int operator()(T val)
{
return val<_nThreshold?0:1;
}
int _nThreshold;
};
template<typename T>
bool mycomp(T a, T b)
{
return a>b;
}
template <typename T> //模板
class MyCompC //排序:降序
{
public:
bool operator()(const T& x, const T& y) const //双目运算符
{
return x>y;
}
};
void Test()
{
const int N = 5;
int a[N] = {1,2,4,3,5};
outputCont("a",cout,a,a+N); //a:1 2 4 3 5
int b[N];
vector<double> vb(N);
vector<double> vc(N);
transInv(a,b,N);
outputCont("Inv a",cout,b,b+N); //负数Inv a:-1 -2 -4 -3 -5
transSqr(a,b,N);
outputCont("Sqr a",cout,b,b+N); //平方Sqr a:1 4 16 9 25
transCube(a,b,N);
outputCont("Cube a",cout,b,b+N); //立方Cube a:1 8 64 27 125
transInvT(a,b,N);
outputCont("Inv a T",cout,b,b+N); //负数Inv a T:-1 -2 -4 -3 -5
//获得容器首,尾迭代器
transInvT(a,a+N,b,InvT<int>);
transInvT(a,a+N,vb.begin(),InvT<int>);
outputCont("Inv a by iter",cout,vb.begin(),vb.end()); //Inv a by iter:-1 -2 -4 -3 -5
//图像二值化
transInvT(a,a+N,vb.begin(),MyThreshold<int>(2));
outputCont("Inv a by treshold",cout,vb.begin(),vb.end()); //Inv a by treshold:0 1 1 1 1
sort(a,a+N,mycomp<int>);
sort(a,a+N,greater<int>()); //greater内容
sort(a,a+N,MyCompC<int>());
outputCont("a sorted",cout,a,a+N); //降序a sorted:5 4 3 2 1
vb.swap(vc); //将vb和vc两容器内容交换
}
int main()
{
// cout << "Hello World!" << endl;
Test();
return 0;
}
测试结果
二、用set存储学生信息,并进行增删改查操作
容器 分为三种:
顺序容器
array(数组)、vector(向量)、deque(双端队列)、forward_list(单链表)、list(列表)
(有序)关联容器
set(集合)、multiset(多重集合)、map(映射)、multimap(多重映射)
无序关联容器
unordered_set (无序集合)、unordered_multiset(无序多重集合)
unordered_map(无序映射)、unorder_multimap(无序多重映射)
1.顺序容器的接口(不包含单向链表(forward_list)和数组(array))
①构造函数
列表初始化,如vector arr = {1,4,5,7};
②赋值函数
assign
③插入函数
insert(iterator pos, const T& v), 在pos位置插入后,返回新插入元素的迭代器
push_front(只对list和deque), push_back,
emplace_front、emplace 和 emplace_back,这些操作构造而不是拷贝元素到容器中,这些操作分别对应push_front、insert 和push_back,允许我们将元素放在容器头部、一个指定的位置和容器尾部。
④删除函数
erase,clear,pop_front(只对list和deque) ,pop_back
⑤首尾元素的直接访问
front,back
⑥改变大小
resize
2.关联容器的特点和接口
①关联容器的特点
每个关联容器都有一个键(key)
可以根据键高效地查找元素
②接口
构造:列表初始化,如map<string, int> id_map = {{“小明”, 1}, {“李华”, 2}}
插入:insert
删除:erase
查找:find
定界:lower_bound、upper_bound、equal_range
计数:count
集合(set)
集合用来存储一组无重复的元素。由于集合的元素本身是有序的,可以高效地查找指定元素,也可以方便地得到指定大小范围的元素在容器中所处的区间。
代码如下(示例):
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 本身排序是有序的
void TestSet() //学号排序输出
{
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_strName set",cout,studentSet.begin(),studentSet.end());
studentSet.insert(studentInfo("10030", "HHL")); //增加
outputCont("student_strName add", cout, studentSet.begin(), studentSet.end());
studentSet.erase(studentInfo("10003","Wang wu")); //删除
outputCont("student_strName del",cout,studentSet.begin(),studentSet.end());
students[2]._strName = "hhl"; //第三个改成hhl
set<studentInfo> studentmodify(students.begin(),students.end());
outputCont("student_strName mod",cout,studentmodify.begin(),studentmodify.end());
//查未实现
}
测试结果
三、输入一个字符串,用map统计每个字符出现的次数并输出字符及对应的次数
映射:
映射与集合同属于单重关联容器,它们的主要区别在于,集合的元素类型是键本身,而映射的元素类型是由键和附加数据所构成的二元组。
在集合中按照键查找一个元素时,一般只是用来确定这个元素是否存在,而在映射中按照键查找一个元素时,除了能确定它的存在性外,还可以得到相应的附加数据。
代码如下:
//映射
void TestMap()
{
map<string,int> stu;
stu["01"] = 100;
stu["10"] = 99; //重复元素
stu["05"] = 98;
stu["10"] = 95; //重复元素
for(map<string,int>::iterator it=stu.begin();it!=stu.end();it++)
{
cout<<it->first<<" "<<it->second<<endl;
}
map<char, int> s; //用来存储字母出现次数的映射
char c; //存储输入字符
cout<<"please input"<<endl;
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;
}
void Test()
{
cout<<"TestMap:"<<endl;
TestMap(); //01 100;05 98;10 95;
}
int main()
{
// cout << "Hello World!" << endl;
Test();
return 0;
}
测试结果
代码中重复的stu[“10”] = 99; stu[“10”] = 95;只有最后一个输出。set是根据元素值进行排序的集合,所插入的元素在集合中唯一,不存在重复元素
总结
set容器:set是STL中一种标准关联容器。它底层使用平衡的搜索树——红黑树实现,插入删除操作时仅仅需要指针操作节点即可完成,不涉及到内存移动和拷贝,所以效率比较高。
set作为一个容器也是用来存储同一数据类型的数据类型,并且能从一个数据集合中取出数据,在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。应该注意的是set中数元素的值不能直接被改变。C++ STL中标准关联容器set, multiset, map, multimap内部采用的就是一种非常高效的平衡检索二叉树:红黑树,也成为RB树(Red-Black Tree)。RB树的统计性能要好于一般平衡二叉树,所以被STL选择作为了关联容器的内部结构。