关于c++ STL库的一些总结

本人使用c++的STL库的一些总结



前言

以下都是个人在使用c++stl的时候容易忘记的一些代码


String的相关测试

//整数转字符串(转入string内)
int a = 10;
string s1;
s1 += to_string(a);


//获取string整一行
string s1;
getline(cin, s1);


//字符转string
char tmp = 2 + 'A';
string ans;
ans.push_back(tmp);
return ans;



//string转int
string s1 = "0001";
int a = stoi(s1);


//string转ll
stoll



//整型转string
string s1;
int a = 100;
s1 = to_string(a);


//把string变成c的字符串,用于判断结束用的
const char* c;
string s = "1234";
c = s.c_str();


//string截断
string s1 = "abcdef";
string a = s1[i].substr(0, 2);//到a到c,c不计在内。左闭右开
string b = s1[i].substr(2);//c到结尾 cdef

//两个string的比较
std::string s1 = "Hello";
std::string s2 = "Hello";
int val = s1.compare(s2);

Map的细节测试

//以下是测试用的两个仿函数
//
struct CountVal//仿函数是结构体,仿函数内容拷贝
{
	bool operator()(const pair<string, int>& l, const pair<string, int>& r)//堆种小于是排大堆的,大于是排小堆的
	{
		//return l.second > r.second;//堆种小于是排大堆的,大于是排小堆的
		return l.second < r.second;//小于建大堆,大于建小堆
	}
};

struct CountIterVal//仿函数,用迭代器排序的用法
{
	bool operator()(const map<string, int>::iterator& l, const map<string, int>::iterator& r)
	{
		//return l->second > r->second;//堆种小于是排大堆的,大于是排小堆的
		return l->second < r->second;
	}
};

















void map_test1(const vector<string>& fruits, size_t k)
{
	
	map<string, int> countMap;
	for (auto& str : fruits)
	{
		countMap[str]++;//普通map用[]可以做到没有的话插入,有的话增加,拿的是map种的value增加
	}

	// 数据量不大,排序
	// sort,用的是普通map的方法
	
	vector<pair<string, int>> sortV;//用一个vector容器装载map中的类容,应为sort要随机迭代器,vector里面存的是pair
	for (auto& kv : countMap)
	{
		sortV.push_back(kv);//往vector容器中插入map的pair
	}
	//排序
	sort(sortV.begin(), sortV.end(), CountVal());//最后一个是匿名对象,仿函数要传匿名对象有(),模板类传参数不用匿名对象


	//输出
	for (int i = 0; i < k; ++i)
	{
		cout << sortV[i].first << ":" << sortV[i].second << endl;
	}
	cout << endl;


}



void map_test2(const vector<string>& fruits, size_t k)
{
	map<string, int> countMap;//建立一个map
	for (auto& str : fruits)
	{
		countMap[str]++;//普通map用[]可以做到没有的话插入,有的话增加,拿的是map种的value增加
	}


	vector<map<string, int>::iterator> sortV;//把countMap的迭代器拷贝到vector中,拷贝的量会少很多
	
	//往sortV中插countMap中的迭代器
	auto it = countMap.begin();
	while (it != countMap.end())
	{
		sortV.push_back(it);
		++it;
	}

	//对迭代器中内容解引用找scend然后排序,写了个仿函数
	sort(sortV.begin(), sortV.end(), CountIterVal());

	for (int i = 0; i < k; ++i)
	{
		cout << sortV[i]->first << ":" << sortV[i]->second << endl;//如果内部存pair,是个结构提就可以用.来访问,而迭代器是指向pair的指针,只能->来访问
	}
	cout << endl;
}


void map_test3(const vector<string>& fruits, size_t k)
{
	map<string, int> countMap;//建立一个map
	for (auto& str : fruits)
	{
		countMap[str]++;//普通map用[]可以做到没有的话插入,有的话增加,拿的是map种的value增加
	}


	//multimap中存的是与map相反的kv这样就可以统计次数了,可以存多个相等的k
	//greater排降序
	multimap < int, string, greater<int>> sortMap;//用multimap排map,这里开可以给sortMap一个greater<int>的防函数参数用于控制排序方式,是参数,所以不用匿名()
	for (auto& kv : countMap)						//让multimp存的key和value与原来countMap的反着来达到目的
	{
		sortMap.insert(make_pair(kv.second, kv.first));
	}

	//auto it= sortMap.rbegin();如果multimap中是less的仿函数那么就用rbegin(),如果是greater就用begin()
	auto it= sortMap.begin();
	while (k--)
	{
		cout <<it->first << ":" << it->second << endl;
		it++;
	}
}






void map_test4(const vector<string>& fruits, size_t k)
{
	map<string, int> countMap;
	for (auto& str : fruits)
	{
		countMap[str]++;
	}

	// 堆
	//可以反向迭代器取top k(反着走k次),也可以用堆(优先级)队列取top k
	//仿函数CountVal找的是second来比较
	//大于是小堆,小堆可以找topK,但是这样会该表原来用vector来存的效果,vector中小于就是升序,大于是降序
	priority_queue<pair<string, int>, vector<pair<string, int>>, CountVal> pq;
	for (auto& kv : countMap)
	{
		pq.push(kv);
	}

	while (k--)
	{
		cout << pq.top().first << ":"<<pq.top().second << endl;
		pq.pop();
	}
	cout << endl;
}


void map_test5(const vector<string>& fruits, size_t k)
{
	map<string, int> countMap;
	for (auto& str : fruits)
	{
		countMap[str]++;
	}

	priority_queue<map<string, int>::iterator, vector<map<string, int>::iterator>, CountIterVal> pq;//类模板传参数,最有一个仿函数是参数,函数模板传参数
	auto it = countMap.begin();
	while (it != countMap.end())
	{
		pq.push(it);
		++it;
	}

	while (k--)
	{
		cout << pq.top()->first << ":" << pq.top()->second << endl;
		pq.pop();
	}
	cout << endl;
}





void map_test6()
{
	map<string, string> dict;
	pair<string, string> kv1("sort", "排序");//第一种写法
	dict.insert(kv1);
	//
	dict.insert(pair<string, string>("string", "字符串"));//第二种写法
	// 自动推到类型
	dict.insert(make_pair("test", "测试"));  // 使用它,第三种写法




	//map<string, string>::iterator it = dict.begin();
	auto it = dict.begin();
	while (it != dict.end())//不能用迭代器修改k
	{
		//it->first = "wess";
		//it->second = "wess";

		//cout << *it << " ";
		//cout << (*it).first << ":" << (*it).second << endl;
		cout << it->first << ":" << it->second << endl;
		++it;
	}
	cout << endl;

	for (auto& kv : dict)
	{
		cout << kv.first << ":" << kv.second << endl;
	}
	cout << endl;
}




void map_test8()
{
	string arr[] = { "苹果", "苹果", "香蕉", "苹果", "香蕉", "苹果", "樱桃" };
	map<string, int> countMap;
	/*for (auto& str : arr)
	{
		auto ret = countMap.find(str);//find找到的是中序遍历第一个出现的,也就是这个元素的最左节点
		if (ret == countMap.end())
		{
			countMap.insert(make_pair(str, 1));
		}
		else
		{
			ret->second++;
		}
	}*/


	//[]的实现是这样的
	//for (auto& str : arr)
	//{
	//	auto kv = countMap.insert(make_pair(str, 1));
	//	if (kv.second == false)
	//	{
	//		kv.first->second++;//这里kv是个pair他的第一个指向的是在map中存在的,前面找的那个元素地址,而这个节点里面又有个pair(及外层piar的first就是这个节点,这个节点再指向second就是水果的个数
	//	}
	//}
	for (auto& str : arr)
	{
		countMap[str]++;
	}

	for (auto& kv : countMap)
	{
		cout << kv.first << ":" << kv.second << endl;
	}
	cout << endl;
}


void map_test9()
{
	map<string, string> dict;
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("left", "左边"));//应为map是k排序,k一样不会管value所以不会插入
	dict.insert(make_pair("left", "剩余"));//应为map是k排序,k一样不会管value所以不会插入

	//[]返回的是对应k的value的引用
	dict["left"] = "剩余"; // 修改
	dict["test"];          // 插入
	cout << dict["sort"] << endl; // 查找

	dict["string"] = "字符串"; // 插入+修改
}


int main()
{
	vector<string> v = { "苹果", "苹果", "香蕉", "苹果", "香蕉", "苹果", "樱桃", "哈密瓜", "榴莲", "榴莲", "苹果" };

//多种排序方式

	map_test1(v, 3);//(test1用map往vector中深拷贝内容加排序的方式实现topk问题)
	map_test2(v, 3);//(test2用map往vector中存map的迭代器(减少拷贝)的方式实现topk问题)

	map_test3(v, 3);//(test3用map往multimap反着存kv的方式实现topk问题(但是是深拷贝))

	map_test4(v, 3);//(用堆pq的方式深拷贝map的值做排序)
	map_test5(v, 3);//(用堆pq但是存迭代器的方式做排序)




	map_test6();//(关于map如何插入的问题)

	map_test7();//(没写这个函数)//map的earse删除的也是中序遍历的第一个出现的位置,返回这个位置,但是earse(30)就会全部删光

	map_test8();//[]号的原理和用处,还有find返回的东西是什么

	map_test9()//[]的修改,插入,查找
	return 0;
}

SET的相关测试

void test_set1()
{
	// 排序+去重
	set<int> s;
	s.insert(3);
	s.insert(1);
	s.insert(5);
	s.insert(2);
	s.insert(8);
	s.insert(1);
	s.insert(8);

	//set<int>::iterator it = s.begin();
	auto it = s.begin();

	while (it != s.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	//s.erase(30)如何封装的
	set<int>::iterator pos = s.find(30);
	if (pos != s.end())
	{
		// pos必须一个有效位置的迭代器
		s.erase(pos);
	}

	//下面这个就是由两面封装下来的
	cout << s.erase(30) << endl;
	cout << s.erase(3) << endl;

	for (auto e : s)
	{
		cout << e << " ";
	}
	cout << endl;
}




void test_multiset()
{
	// 排序
	multiset<int> s;
	s.insert(3);
	s.insert(1);
	s.insert(5);
	s.insert(2);
	s.insert(8);
	s.insert(1);
	s.insert(8);
	s.insert(1);
	s.insert(1);

	auto it = s.begin();
	while (it != s.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;


	// find 的val有多个值时,返回中序第一个val值所在节点的迭代器
	multiset<int>::iterator pos = s.find(8);
	while (pos != s.end())
	{
		cout << *pos << " ";
		++pos;
	}
	cout << endl;

	/*pos = s.find(1);
	while (pos != s.end() && *pos == 1)
	{
		auto next = pos;
		++next;

		s.erase(pos);

		pos = next;
	}*/

	cout << s.erase(1) << endl;//erase返回size_t删除的个数

	for (auto e : s)
	{
		cout << e << " ";
	}
	cout << endl;

	pos = s.find(5);
	if (pos != s.end())
	{
		// 不允许修改,set,map的k都不给修改
		//*pos += 10;
	}
}




int main()
{
	test_set1();
	test_multiset();

	return 0;

}

总结

STL等相关的使用后续后不断更新,此博客相当于自己的使用记录

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Ap0stoL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值