- 一、撰写自己的算法和函数,结合容器和迭代器解决序列变换
- 1.1 实现方法
- 1.2 代码实现
- 1.3 图像二值化
- 二、用set存储学生信息,并进行增删改查 *** 作
- 2.1 实现方法
- 2.2 代码实现
- 三、map统计字符
- 3.1 实现方法
- 3.2 代码实现
这里实现了取反、平方、立方的计算。采用的容器是vector数组,在实现的函数里加上了模板,这样就能灵活针对不同的数据类型进行 *** 作。
关于vector容器,和数组十分相似,也称为单端数组。不同之处是数组是静态空间,在创建的时候就要规定好长度,而vector可以动态扩展。关于它的一些 *** 作函数就不在这里全部说明了。
下面展示代码,分别是:取反、平方、立方
//取反 templatevector myNegate(vector &v) { vector v1; //在赋值的时候就不用迭代器遍历了,而是普通的for循环遍历 //像数组一样,v[i]的方式也能读取vector的对应位置元素 //v.size()返回的是它的长度 for (int i = 0; i < v.size(); i++) { v1.push_back(-v[i]); } return v1; } //平方 template vector mySquare(vector & v) { vector v1; for (int i = 0; i < v.size(); i++) { v1.push_back(pow(v[i],2)); } return v1; } //立方 template vector myCube(vector & v) { vector v1; for (int i = 0; i < v.size(); i++) { v1.push_back(pow(v[i], 3)); } return v1; }
创建函数进行测试
void test01() { vectorv; vector ::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 v1; v1 = myNegate(v); cout << "取反的结果如下:" << endl; for (it = v1.begin(); it != v1.end(); it++) { cout << *it< v2; v2 = mySquare(v); cout << "平方的结果如下:" << endl; for (it = v2.begin(); it != v2.end(); it++) { cout << *it << endl; } vector v3; v3 = myCube(v); cout << "立方的结果如下:" << endl; for (it = v3.begin(); it != v3.end(); it++) { cout << *it << endl; } }
运行结果
图像二值化,就是将灰度图像(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:.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容器,它是一种关联式容器,底层结果用二叉树实现,它不允许容器中有重复的元素。另外,所有元素在插入的时候都会自动被排序。因为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::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:
- map中所有元素都是pair
- pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
- 所有元素都会根据元素的键值自动排序
- pair是成对出现的数据,利用对组可以返回两个数据
- 属于关联式容器,底层结构是用二叉树实现。
- 可以根据key值快速找到value值
因此,根据搜索key,即字母,看它是否存在。如果存在,则它的value+1,不存在则插入,让这个字母作为新的键插入,并让其值=1
void test03() { string str = "qwehjadnfklsamdpDSAKJDNKVNADFNAndkjasndkjasdfjodsfjsknfmbq"; mapm; for (int i = 0; i < str.length(); i++) { if (m.end() != m.find(str[i])) { m[str[i]]++; } else { m.insert(pair (str[i], 1)); } } for (auto it : m) { cout << it.first << " " << it.second << endl; } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)