文章目录
一、撰写自己的算法和函数,结合容器和迭代器解决序列变换
1.1 实现方法
这里实现了取反、平方、立方的计算。采用的容器是vector数组,在实现的函数里加上了模板,这样就能灵活针对不同的数据类型进行操作。
关于vector容器,和数组十分相似,也称为单端数组。不同之处是数组是静态空间,在创建的时候就要规定好长度,而vector可以动态扩展。关于它的一些操作函数就不在这里全部说明了。
1.2 代码实现
下面展示代码,分别是:取反、平方、立方
//取反
template <typename T>
vector<T> myNegate(vector<T> &v) {
vector<T> v1;
//在赋值的时候就不用迭代器遍历了,而是普通的for循环遍历
//像数组一样,v[i]的方式也能读取vector的对应位置元素
//v.size()返回的是它的长度
for (int i = 0; i < v.size(); i++) {
v1.push_back(-v[i]);
}
return v1;
}
//平方
template <typename T>
vector<T> mySquare(vector<T>& v) {
vector<T> v1;
for (int i = 0; i < v.size(); i++) {
v1.push_back(pow(v[i],2));
}
return v1;
}
//立方
template <typename T>
vector<T> myCube(vector<T>& v) {
vector<T> v1;
for (int i = 0; i < v.size(); i++) {
v1.push_back(pow(v[i], 3));
}
return v1;
}
创建函数进行测试
void test01() {
vector<double> v;
vector<double>::iterator it;
v.push_back(-10.1);//在尾部插入数据
v.push_back(20.99);
v.push_back(30.77);
v.push_back(-40.50);
v.push_back(50.60);
cout << "原数据为:" << endl;
//用迭代器进行遍历
for (it = v.begin(); it != v.end(); it++) {
cout << *it << endl;
}
vector<double> v1;
v1 = myNegate(v);
cout << "取反的结果如下:" << endl;
for (it = v1.begin(); it != v1.end(); it++) {
cout << *it<<endl;
}
vector<double> v2;
v2 = mySquare(v);
cout << "平方的结果如下:" << endl;
for (it = v2.begin(); it != v2.end(); it++) {
cout << *it << endl;
}
vector<double> v3;
v3 = myCube(v);
cout << "立方的结果如下:" << endl;
for (it = v3.begin(); it != v3.end(); it++) {
cout << *it << endl;
}
}
运行结果
1.3 图像二值化
图像二值化,就是将灰度图像(0-255)转换为只有两个值的图像。即要么黑,要么白。
void main()
{
int threshold = 200;
FILE* stream = fopen("D:\\img.bmp", "rb");
if (stream == NULL)
{
cout << "文件不存在" << endl;
return;
}
int sizeFileHeader = sizeof(BITMAPFILEHEADER);
int sizeInfoHeader = sizeof(BITMAPINFOHEADER);
BITMAPFILEHEADER* bitmapFileHeader = new BITMAPFILEHEADER[sizeFileHeader + 1];
BITMAPINFOHEADER* bitmapInfoHeader = new BITMAPINFOHEADER[sizeInfoHeader + 1];
memset(bitmapFileHeader, 0, sizeFileHeader + 1);
memset(bitmapInfoHeader, 0, sizeInfoHeader + 1);
fread(bitmapFileHeader, sizeof(char), sizeFileHeader, stream);
fseek(stream, sizeFileHeader, 0);
fread(bitmapInfoHeader, sizeof(char), sizeInfoHeader, stream);
fseek(stream, sizeInfoHeader + sizeFileHeader, 0);
RGBQUAD* pRgbQuards = new RGBQUAD[256];
for (int k = 0; k < 256; k++)
{
fread(&pRgbQuards[k], sizeof(RGBQUAD), 1, stream);
}
int count = (((bitmapInfoHeader->biWidth) * 8 + 31) / 32) * 4 - bitmapInfoHeader->biWidth * (bitmapInfoHeader->biBitCount / 8);
BYTE* tempData = new BYTE[count + 1];
memset(tempData, 0, count + 1);
fseek(stream, sizeFileHeader + sizeInfoHeader + 256 * sizeof(RGBQUAD), 0);
BYTE** data = new BYTE * [bitmapInfoHeader->biHeight];
for (int i = 0; i < bitmapInfoHeader->biHeight; i++)
{
data[i] = new BYTE[bitmapInfoHeader->biWidth];
for (int j = 0; j < bitmapInfoHeader->biWidth; j++)
{
fread(&data[i][j], sizeof(char), 1, stream);
if (data[i][j] > threshold)
data[i][j] = 255;
else
data[i][j] = 0;
}
for (int n = 0; n < count; n++)
{
fread(&tempData[n], sizeof(char), 1, stream);
}
}
fclose(stream);
//写入。。
FILE* fileWrite = fopen("D:\\9.bmp", "wb");
fwrite(bitmapFileHeader, sizeof(char), sizeof(BITMAPFILEHEADER), fileWrite);
fwrite(bitmapInfoHeader, sizeof(char), sizeof(BITMAPINFOHEADER), fileWrite);
fwrite(pRgbQuards, sizeof(RGBQUAD), 256, fileWrite);
for (int i = 0; i < bitmapInfoHeader->biHeight; i++)
{
for (int j = 0; j < bitmapInfoHeader->biWidth; j++)
{
fwrite(&data[i][j], sizeof(BYTE), 1, fileWrite);
}
for (int m = 0; m < count; m++)
fwrite(&tempData[m], sizeof(char), 1, fileWrite);
}
fclose(fileWrite);
cout << "success" << endl;
}
原灰度图像
使用c++代码实现
对比matlab的imbinarize:
二、用set存储学生信息,并进行增删改查操作
2.1 实现方法
关于set容器,它是一种关联式容器,底层结果用二叉树实现,它不允许容器中有重复的元素。另外,所有元素在插入的时候都会自动被排序。因为set容器默认排序规则为从小到大,所以我们可以创建仿函数改变排序规则。
2.2 代码实现
增删改查:
增:
用insert函数
代码和运行结果如下:
删除:
clear();
//清除所有元素erase(pos);
//删除pos迭代器所指的元素,返回下一个元素的迭代器。erase(beg, end);
//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。erase(elem);
//删除容器中值为elem的元素。
下面两个是删除单个值
这样是删除全部元素
查询:
find(key);
//查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();count(key);
//统计key的元素个数
//查找
set<Student>::iterator pos = s.find(stu1);
if (pos != s.end())
{
cout << "找到了元素 : " << pos->m_Name <<" " << pos->m_ID << endl;
}
else
{
cout << "未找到元素" << endl;
}
//统计
int num = s.count(stu2);
cout << "num = " << num << endl;
修改:
set是不能像数组那样直接拿出第几个元素的
并且set的迭代器it有const修饰符,所以它不能直接修改元素的值。
所以我的做法是:因为set里的元素都是唯一的,所以如果要修改某个元素,它必须事先存在,然后找到它把它删除。最后再把新的数据插入。实现代码如下:
Student fs("马里奥", 1);
it = s.find(fs);
if (it != s.end()) {
s.erase(it);
Student ns("瓦力欧",1);
s.insert(ns);
}
else {
cout << "查不到" << endl;
}
这里的本质还是 查-删-增。
三、map统计字符
3.1 实现方法
关于map:
- map中所有元素都是pair
- pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
- 所有元素都会根据元素的键值自动排序
- pair是成对出现的数据,利用对组可以返回两个数据
- 属于关联式容器,底层结构是用二叉树实现。
- 可以根据key值快速找到value值
因此,根据搜索key,即字母,看它是否存在。如果存在,则它的value+1,不存在则插入,让这个字母作为新的键插入,并让其值=1
3.2 代码实现
void test03() {
string str = "qwehjadnfklsamdpDSAKJDNKVNADFNAndkjasndkjasdfjodsfjsknfmbq";
map<char, int> m;
for (int i = 0; i < str.length(); i++) {
if (m.end() != m.find(str[i])) {
m[str[i]]++;
}
else {
m.insert(pair<char, int>(str[i], 1));
}
}
for (auto it : m)
{
cout << it.first << " " << it.second << endl;
}
}