
- 一、撰写自己的算法和函数,结合容器和迭代器解决序列变换
- 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() {
vector v;
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";
map m;
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条)