目录
一.实验内容:
二.实验实现:
1.结合容器和迭代器解决序列变换(如取反、平方、立方),像素变换(二值化、灰度拉伸);
1.1.容器和迭代器相关介绍:
1.2.序列变换(如取反、平方、立方):
?1.3.像素变换(二值化、灰度拉伸):
1.4.sort函数:
2.用set存储学生信息,并进行增删改查操作:
2.1.学生类:
2.2.增删改查函数代码:
3.输入一个字符串,用map统计每个字符出现的次数并输出字符及对应的次数:
????????STL 是“Standard Template Library”的缩写,中文译为“标准模板库”。C++ 对模板(Template)支持得很好,STL 就是借助模板把常用数据结构及其算法都实现了一遍,并且做到了数据结构和算法的分离。
一.实验内容:
1.撰写自己的算法和函数,结合容器和迭代器解决序列变换(如取反、平方、立方),像素变换(二值化、灰度拉伸);
2.用set存储学生信息,并进行增删改查操作;
3.输入一个字符串,用map统计每个字符出现的次数并输出字符及对应的次数。
二.实验实现:
1.结合容器和迭代器解决序列变换(如取反、平方、立方),像素变换(二值化、灰度拉伸);
1.1.容器和迭代器相关介绍:
????????容器:是一种数据结构, 在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对像的指针,这种对象类型就叫做容器。一般分为顺序容器:vector(向量)、list(列表)、deque(队列);关联容器:map(集合)、set(映射)、multimap(多重集合)、multiset(多重映射);
????????迭代器:提供了访问容器中对象的方法。例如,可以使用一对迭代器指定list或vector中的一定范围的对象。迭代器就如同一个指针。事实上,C++的指针也是一种迭代器。但是,迭代器也可以是那些定义了operator*()以及其他类似于指针的操作符地方法的类对象;常见的一些迭代器类型:iterator、const_iterator、reverse_iterator和const_reverse_iterator。 ?
1.2.序列变换(如取反、平方、立方):
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 transSqrT(T a[],T b[],int nNum) //对元素求平方
{
for(int i=0;i<nNum;i++)
{
b[i] = a[i]*a[i];
}
}
template <typename T>
void transPow(T a[],T b[],int nNum) //对元素求立方
{
for(int i=0;i<nNum;i++)
{
b[i] = a[i]*a[i]*a[i];
}
}
template <typename T>
void outputCont(string strName,ostream& os,T begin,T end) //输入输出元素
{
os<<strName<<":";
for(;begin!=end;begin++)
{
os<<*begin<<"\t";
}
os<<endl;
}
上述所用的模板相关知识,可以查看C++ 实验3 模板_Jianwei Tao的博客-CSDN博客
测试代码:
void Testone()
{
const int N=5;
int a[N] = {1,2,3,4,5};
outputCont("a的值:",cout,a,a+N);
int b[N];
vector<double> vb(N);
transInv(a,b,N);//对元素取反
outputCont("Inv a(对元素取反后的值)",cout,b,b+N);
transSqr(a,b,N);//对元素求平方
outputCont("Sqr a(对元素求平方后的值)",cout,b,b+N);
transPow(a,b,N);//对元素求立方
outputCont("Pow a(对元素求立方后的值)",cout,b,b+N);
}
?Vectors:将元素置于一个动态数组中加以管理,可以随机存取元素(用索引直接存取),数组尾部添加或移除元素非常快速。但是在中部或头部安插元素比较费时;
运行结果:
?1.3.像素变换(二值化、灰度拉伸):
template<typename T> //二值化
class MyThreshold
{
public:
int _nThreshold;
MyThreshold(int n=128):_nThreshold(n){}
int operator()(T val)
{
return val<_nThreshold?0:1; //小于_nThreshold返回0
}
};
//通过查看一组数据中有几个是小于2的,可用作图像二值化处理,根据阈值将像素分为两个部分
1.4.sort函数:
测试代码(sort函数的具体几种运用):
void TestSort()
{
const int N = 7;
int c[N] = {34,31,35,32,33,37,30};
outputCont("输出 c 值",cout,c,c+N);
sort(c,c+N); //默认是按照升序排序
outputCont("排序后的值",cout,c,c+N);
//sort函数包含在#include <algorithm>的标准库中,sort()函数有三个参数,依次为要排序数据的起始地址,结束地址,排序的方法
sort(c,c+N,mycoup<int>); //将用于比较的模板函数作用第三个参数,指定排序方式,使其按照降序排列
outputCont("降序排列后的值",cout,c,c+N);
//标准库模板类,在#include <functional>库里面,表示内置类型从大到小排序,less表示从小到大排序
sort(c,c+N,greater<int>());
outputCont("内置类型从大到小排序",cout,c,c+N);
sort(c,c+N,less<int>());
outputCont("内置类型从小到大排序",cout,c,c+N);
sort(c,c+N,MyCompC<int>()); //自定义模板类
outputCont("自定义的排序",cout,c,c+N);
}
?自定义的模板类:
template <typename T>自定义模板类
class MyCompC
{
public:
bool operator()(const T& x, const T& y) const
{
return x<y; //升序,x>y:降序
}
};
运行结果:
2.用set存储学生信息,并进行增删改查操作:
2.1.学生类:
class studentInfo{
public:
string _strNo;//学号
string _strName; //姓名
studentInfo();
studentInfo(string strNo,string strName)
{
_strNo = strNo;
_strName = 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;
}
};
定义学生类,用来存储学生信息;
2.2.增删改查函数代码:
void TestSet()
{
vector<studentInfo> students;
students.push_back(studentInfo("51","Jianwei Tao"));//push_back在Vector最后添加一个元素
students.push_back(studentInfo("50","Wenlong Xie"));
students.push_back(studentInfo("49","Haohao Wu"));
students.push_back(studentInfo("52","Ruijie Ren"));
students.push_back(studentInfo("50","Wenlong Xie"));
set<studentInfo> studentSet(students.begin(),students.end());
outputCont("set容器内值:",cout,studentSet.begin(),studentSet.end());
//插入元素
studentSet.insert(studentInfo("99","jiqin"));
outputCont("插入后set数据:",cout,studentSet.begin(),studentSet.end());
//insert()函数返回值是pair<set<int>::iterator,bool>,bool标志着插入是否成功(使用时用second表示返回值的第二个位置)
//删除元素
//移除set容器内元素值为value的所有元素
studentSet.erase(studentInfo("99","jiqin"));
outputCont("删除99,jiqin元素值后结果:",cout,studentSet.begin(),studentSet.end());
//移除pos位置的元素,无返回值
set<studentInfo>::iterator iter = studentSet.begin();
studentSet.erase(iter);
outputCont("移除首位值结果:",cout,studentSet.begin(),studentSet.end());
//修改元素的值
for(set<studentInfo>::iterator it = studentSet.begin();it!=studentSet.end();it++)
{
if((it->_strNo)=="51")
{
studentSet.erase(studentInfo("51",""));
studentSet.insert(studentInfo("51","Jianwei"));
}
}
outputCont("修改后输出值",cout,studentSet.begin(),studentSet.end());
//查找元素
//find会挨个查找set,查找成功返回一个指向指定元素的迭代器,找不到则返回end()
cout<<"查找结果:";
if(studentSet.find(studentInfo("11","Jianwei"))!=studentSet.end())
{
cout<<"存在该元素"<<endl;
}
else
{
cout<<"不存在该元素"<<endl;
}
//清空set
studentSet.clear();
if(studentSet.empty())
{
cout<<"set已清空"<<endl;
}
}
?Set:内部的元素依据其值自动排序,Set内的相同数值的元素只能出现一次
输出结果:
3.输入一个字符串,用map统计每个字符出现的次数并输出字符及对应的次数:
测试代码:
void TestMap()
{
map<string,int> stu;
stu["01"] = 100;
stu["02"] = 99;
stu["04"] = 96;
stu["03"] = 98;
stu["02"] = 97;
cout<<"map值:";
for(map<string,int>::iterator it=stu.begin();it!=stu.end();it++)
{
cout<<it->first<<":"<<it->second<<"\t";
}
cout<<endl;
//增加元素
stu.insert(pair<string,int>("05", 55));
// 用insert函数插入value_type数据
stu.insert(map<string,int>::value_type("06",66));
// 用数组方式插入
stu["01"] = 11;
stu["07"] = 77;
cout<<"增加元素后的值:";
for(map<string,int>::iterator it=stu.begin();it!=stu.end();it++)
{
cout<<it->first<<":"<<it->second<<"\t";
}
cout<<endl;
//删除元素
//迭代器刪除
map<string,int>::iterator it;
it = stu.find("05");
stu.erase(it);
//关键字删除
int n = stu.erase("07"); //如果刪除了返回1,否则返回0
if(n)
{
cout<<"刪除成功"<<endl;
}
else
{
cout<<"刪除失败"<<endl;
}
cout<<"删除元素后的值:";
for(map<string,int>::iterator it=stu.begin();it!=stu.end();it++)
{
cout<<it->first<<":"<<it->second<<"\t";
}
cout<<endl;
int len=stu.size(); //获取到map中映射的次数
cout<<"字符长度:"<<len<<endl;
//用迭代器范围刪除stu.erase(stu.begin(), stu.end()),等同于mapStudent.clear();
//输入一个字符串,用map统计每个字符出现的次数并输出字符及对应的次数
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<<"\t";
}
cout<<endl;
}
?Map的元素是成对的键值/实值,内部的元素依据其值自动排序,Map内的相同数值的元素只能出现一次。
运行结果:
|