C++之STL应用

C++之STL应用,第1张

C++之STL应用

文章目录
    • 一、撰写自己的算法和函数,结合容器和迭代器解决序列变换
      • 1.1 实现方法
      • 1.2 代码实现
      • 1.3 图像二值化
    • 二、用set存储学生信息,并进行增删改查 *** 作
      • 2.1 实现方法
      • 2.2 代码实现
    • 三、map统计字符
      • 3.1 实现方法
      • 3.2 代码实现

一、撰写自己的算法和函数,结合容器和迭代器解决序列变换 1.1 实现方法

这里实现了取反、平方、立方的计算。采用的容器是vector数组,在实现的函数里加上了模板,这样就能灵活针对不同的数据类型进行 *** 作。
关于vector容器,和数组十分相似,也称为单端数组。不同之处是数组是静态空间,在创建的时候就要规定好长度,而vector可以动态扩展。关于它的一些 *** 作函数就不在这里全部说明了。

1.2 代码实现

下面展示代码,分别是:取反、平方、立方

//取反
template 
vector 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;
	}
}

运行结果

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:.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::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 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;
	}
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5618846.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存