C++STL

C++STL容器部分

定长数组

  • array

  • #include <array>
    #include <iostream>
    #include <string>
    using namespace std;
    //size_t unsigned int 
    template <class _Ty,size_t size>
    class MyArray 
    {
    public:
    	MyArray() 
    	{
    		memroy = new _Ty[size];
    		//new MM[size]
    		
    	}
    	_Ty& operator[](int index)
    	{
    		return memroy[index];
    	}
    	~MyArray() 
    	{
    		delete[] memroy;
    	}
    public:
    	_Ty* begin() 
    	{
    		return memroy + 0;
    	}
    	_Ty* end() 
    	{
    		return memroy + size;
    	}
    	//类的对象模仿指针的行为
    	class iterator 
    	{
    	public:
    		iterator(_Ty* pmove = nullptr) :pmove(pmove) {}
    		void operator=(_Ty* pmove) 
    		{
    			this->pmove = pmove;
    		}
    		bool operator!=(_Ty* pmove) 
    		{
    			return this->pmove != pmove;
    		}
    		iterator operator++(int) 
    		{
    			this->pmove++;
    			return *this;
    		}
    		_Ty operator*() 
    		{
    			return pmove[0];
    		}
    	protected:
    		_Ty* pmove;
    	};
    
    protected:
    	_Ty* memroy;	//MM
    };
    void testMyArray() 
    {
    	MyArray<int, 3> array1D;
    	for (int i = 0; i < 3; i++) 
    	{
    		array1D[i] = i;
    	}
    	MyArray<int, 3>::iterator iter;
    	for (iter = array1D.begin(); iter != array1D.end(); iter++) 
    	{
    		cout << *iter << "\t";
    	}
    	cout << endl;
    }
    void testArray() 
    {
    	//存储数据的类型是:int  
    //数组长度:3
    //用模板的时候用的都是对象,而不是new一个对象
    	array<int, 3> array1D;
    	array<string, 3>* p = new array<string, 3>;
    	delete p;
    #define MAX 5
    	array<double, 5> dAarray1D;
    	//创建并初始化
    	array<int, 3>  num = { 1,2,3 };
    	for (int i = 0; i < array1D.size(); i++) 
    	{
    		array1D[i] = i;
    	}
    	//迭代器
    }
    void testExOperator() 
    {
    	//使用: 和数组一样的用法
    	//一些函数
    	array<int, 3> test = { 1,2,3 };
    	cout << test.empty() << endl;
    	cout << test.size() << endl;
    	test.fill(5);		//填充所有的元素 ,填充为5
    	for (int v : test)		
    	{
    		cout << v << "\t";
    	}
    	cout << endl;
    	//交换  长度一定是要一样常
    	array<int, 3> test1 = { 0,0,0};
    	test.swap(test1);
    	int cData[3] = { 1,2,3 };   //映射:一种对应关系,数组下标对应元素
    	for (auto v : cData) 
    	{
    		cout << v << "\t";
    	}
    	cout << endl;
    }
    //定长数组处理自定义类型的数据
    class MM
    {
    public:
    	MM() {}
    	MM(string name, int age) :name(name), age(age) {}
    	void print() 
    	{
    		cout << name << "\t" << age << endl;
    	}
    protected:
    	string name;
    	int age;
    };
    void testUserData() 
    {
    	array<MM, 3> mmData;	//	MM array[3];
    	for (int i = 0; i < mmData.size(); i++) 
    	{
    		string name = "name";
    		mmData[i] = MM(name + to_string(i), 16 + i);
    	}
    
    	for (auto v : mmData) 
    	{
    		//v:就是MM的对象
    		v.print();
    		//cout<<v;			//想要这样输出,重载<<运算符
    	}
    	//迭代器访问
    	//对象模仿指针,*迭代器 就是取值运算
    	array<MM, 3>::iterator iter;
    	//begin()
    	//end(): 最后一个位置,不是最后元素的位置
    	(*mmData.begin()).print();
    	//(*mmData.end()).print();  越界访问
    	(*(mmData.end() - 1)).print();
    	for (iter = mmData.begin(); iter != mmData.end(); iter++) 
    	{
    		//(*iter).print();
    		iter->print();
    		//cout<<*iter;		//重载<<
    	}
    }
    //array当做函数参数,返回值都可以
    array<int, 3>&  returnArray(array<int, 3>& temp) 
    {
    	for (int i = 0; i < temp.size(); i++)
    	{
    		temp[i] = i;
    	}
    	return temp;
    }
    
    int main() 
    {
    	testArray();
    	testExOperator();
    	testUserData();
    	cout << "自己写的模板" << endl;
    	testMyArray();
    
    	return 0;
    }

    动态数组

  • vector

    #include <vector>
    #include <iostream>
    #include <string>
    using namespace std;
    //辅助函数:遍历容器
    template <class _Ty>
    void printVector(vector<_Ty>& temp) 
    {
    	for (auto v : temp) 
    	{
    		cout << v << "\t ";
    	}
    	cout << endl;
    }
    //基本用法
    void testCreateVector() 
    {
    	//模板类型:存储数据类型
    	//1.不带长度的创建方式
    	vector<int> vecData;
    	//只能用成员函数做插入
    	for (int i = 0; i < 3; i++) 
    	{
    		vecData.push_back(i);	//尾插法  0   0 1  0 1 2
    	}
    	printVector(vecData);
    	//2.带长度
    	vector<string> strData(3);		//当前动态数组的长度是3
    	//确定长度,可以直接使用数组法插入
    	for (int i = 0; i < 3; i++) 
    	{
    		string name = "name";
    		//只有在确定长度范围以内的可以直接采用数组法插入
    		strData[i] = name + to_string(i);
    	}
    	printVector(strData);
    	//超过的必须用成员函数插入
    	//strData[3] = "name3";    vector subscript out of range  错误
    	strData.push_back("name3");	//在这个函数中做了自动扩增
    	printVector(strData);
    		
    
    	//3.带初始化
    	vector<double> dData = { 1.1,1.23,1.44 };  //自动算出长度为3
    	printVector(dData);
    
    	//猜谜
    	vector<int> intData(3);   
    	intData.push_back(1111);  //在原来内存的后面扩增
    	printVector(intData);	  //0 0 0 1111
    
    	//迭代器遍历
    	vector<string>::iterator iter;
    	for (iter = strData.begin(); iter != strData.end(); iter++) 
    	{
    		cout << *iter << "\t";
    	}
    	cout << endl;
    
    }
    //自定义类型数据
    class MM 
    {
    public:
    	MM(string name, int age) :name(name), age(age) {}
    	friend ostream& operator<<(ostream& out, const MM& temp) 
    	{
    		out << temp.name << "\t" << temp.age;
    		return out;
    	}
    protected:
    	string name;
    	int age;
    };
    void testUserData() 
    {
    	vector<MM> mmData;
    	for (int i = 0; i < 3; i++) 
    	{
    		string name = "name";
    		mmData.push_back(MM(name + to_string(i), 18 + i));
    	}
    	//二进制“<<”: 没有找到接受“MM”类型的右操作数的运算符(或没有可接受的转换)
    	printVector(mmData);
    }
    
    void testExOperator() 
    {
    	vector<int> iData = { 1,2,3,4 };
    	cout << iData.size() << endl;		//当前容器中的元素个数
    	cout << iData.empty() << endl;		//判断是否为空   return size==0; 有元素返回false
    	cout << iData.front() << endl;		//访问第一个元素
    	cout << iData.back() << endl;		//访问最后一个元素
    	cout << iData.at(2) << endl;		//下标访问
    	cout << iData[2] << endl;			//和at(2)一样的效果 表示
    	//修改
    	iData.emplace(iData.begin() + 2, 100); //修改下标是2位置的元素为100
    	printVector(iData);
    	iData.emplace_back(999);			//和push_back一样的功能
    	iData.emplace(iData.begin(), 1111);	//修改第一个元素
    										//删除函数
    	//iData.erase(iData.begin() + 2);   //数组只有伪删除,没有删除操作
    	printVector(iData);
    
    	//批量复制
    	int array[] = { 1,2,3 };
    	vector<int> vecData;
    	vecData.assign(array, array + 3);   //不需要起始长度
    	printVector(vecData);
    }
    int main() 
    {
    	testCreateVector();
    	testUserData();
    	testExOperator();
    	return 0;
    }

    array与vector嵌套

  • #include <iostream>
    #include <array>
    #include <vector>
    #include <string>
    #include <ctime>
    #include <cstdlib>
    using namespace std;
    void testArrayVsArray() 
    {
    	array<array<int, 3>, 4> arrData;  //int arrData[4][3]
    	for (int i = 0; i < 4; i++) 
    	{
    		for (int j = 0; j < 3; j++) 
    		{
    			arrData[i][j] = i * j;
    			cout << arrData[i][j] << "\t";
    		}
    		cout << endl;
    	}
    }
    void testVectorVsVector() 
    {
    	srand((unsigned int)time(nullptr));
    	vector<vector<int>> vecData;
    	//一般vecotor 采用的是push_back插入
    	for (int i = 0; i < 4; i++) 
    	{
    		vector<int> temp;
    		//rand()%3 [0,2]  [2,4]
    		for (int j = 0; j < rand()%3+2; j++) 
    		{
    			temp.push_back(i * j);
    		}
    		vecData.push_back(temp);
    	}
    	//不等列数的二位数组
    	for (int i = 0; i < vecData.size(); i++) 
    	{
    		for (int j = 0; j < vecData[i].size(); j++) 
    		{
    			cout << vecData[i][j] << "\t";
    		}
    		cout << endl;
    	}
    }
    void testArrayVsVector()
    {
    	array<vector<int>, 3> vecArr;
    	vector<int> vec1[3] = { { 1,2,3 } , {1,2,3,4}, {1,2}};
    	for (int i = 0; i < vecArr.size(); i++) 
    	{
    		vecArr[i] = vec1[i];
    	}
    	//不等列数的二位数组
    	for (int i = 0; i < vecArr.size(); i++)
    	{
    		for (int j = 0; j < vecArr[i].size(); j++)
    		{
    			cout << vecArr[i][j] << "\t";
    		}
    		cout << endl;
    	}
    	vector<array<array<vector<int>, 3>, 3>> vec;
    	//慢慢剥洋葱即可
    	array<array<vector<int>, 3>, 3> test;
    	for (int i = 0; i < 3; i++) 
    	{
    		test[i] = vecArr;		//vecArr: array<vector<int>, 3>
    	}
    	vec.push_back(test);
    	
    	vector<array<array<vector<int>, 3>, 3>> test;
    	//上面一行 等效下面两行
    	using Data = array<array<vector<int>, 3>, 3>;
    	vector<Data> test2;
    
    	array<array<vector<int>, 3>, 3> test3;
    	//上面一行 等效下面两行
    	using Data2 = array<vector<int>, 3>;
    	array<Data2, 3>  test3;
    }
    
    void testVectorVsArray() 
    {
    	vector<array<int, 3>> arrVec;
    	array<int, 3>  arr[3] = { { 1,2,3 } , {1,2,3}, {1,2,3}};
    	for (int i = 0; i < 3; i++) 
    	{
    		arrVec.push_back(arr[i]);
    	}
    	for (int i = 0; i < arrVec.size(); i++)
    	{
    		for (int j = 0; j < arrVec[i].size(); j++)
    		{
    			cout << arrVec[i][j] << "\t";
    		}
    		cout << endl;
    	}
    }
    
    int main() 
    {
    	testArrayVsArray();
    	testVectorVsVector();
    	testArrayVsVector();
    	testVectorVsArray();
    	return 0;
    }

    array与vector嵌套

    #include <iostream>
    #include <array>
    #include <vector>
    #include <string>
    #include <ctime>
    #include <cstdlib>
    using namespace std;
    void testArrayVsArray() 
    {
    	array<array<int, 3>, 4> arrData;  //int arrData[4][3]
    	for (int i = 0; i < 4; i++) 
    	{
    		for (int j = 0; j < 3; j++) 
    		{
    			arrData[i][j] = i * j;
    			cout << arrData[i][j] << "\t";
    		}
    		cout << endl;
    	}
    }
    void testVectorVsVector() 
    {
    	srand((unsigned int)time(nullptr));
    	vector<vector<int>> vecData;
    	//一般vecotor 采用的是push_back插入
    	for (int i = 0; i < 4; i++) 
    	{
    		vector<int> temp;
    		//rand()%3 [0,2]  [2,4]
    		for (int j = 0; j < rand()%3+2; j++) 
    		{
    			temp.push_back(i * j);
    		}
    		vecData.push_back(temp);
    	}
    	//不等列数的二位数组
    	for (int i = 0; i < vecData.size(); i++) 
    	{
    		for (int j = 0; j < vecData[i].size(); j++) 
    		{
    			cout << vecData[i][j] << "\t";
    		}
    		cout << endl;
    	}
    }
    void testArrayVsVector()
    {
    	array<vector<int>, 3> vecArr;
    	vector<int> vec1[3] = { { 1,2,3 } , {1,2,3,4}, {1,2}};
    	for (int i = 0; i < vecArr.size(); i++) 
    	{
    		vecArr[i] = vec1[i];
    	}
    	//不等列数的二位数组
    	for (int i = 0; i < vecArr.size(); i++)
    	{
    		for (int j = 0; j < vecArr[i].size(); j++)
    		{
    			cout << vecArr[i][j] << "\t";
    		}
    		cout << endl;
    	}
    	vector<array<array<vector<int>, 3>, 3>> vec;
    	//慢慢剥洋葱即可
    	array<array<vector<int>, 3>, 3> test;
    	for (int i = 0; i < 3; i++) 
    	{
    		test[i] = vecArr;		//vecArr: array<vector<int>, 3>
    	}
    	vec.push_back(test);
    	
    	vector<array<array<vector<int>, 3>, 3>> test;
    	//上面一行 等效下面两行
    	using Data = array<array<vector<int>, 3>, 3>;
    	vector<Data> test2;
    
    	array<array<vector<int>, 3>, 3> test3;
    	//上面一行 等效下面两行
    	using Data2 = array<vector<int>, 3>;
    	array<Data2, 3>  test3;
    }
    
    void testVectorVsArray() 
    {
    	vector<array<int, 3>> arrVec;
    	array<int, 3>  arr[3] = { { 1,2,3 } , {1,2,3}, {1,2,3}};
    	for (int i = 0; i < 3; i++) 
    	{
    		arrVec.push_back(arr[i]);
    	}
    	for (int i = 0; i < arrVec.size(); i++)
    	{
    		for (int j = 0; j < arrVec[i].size(); j++)
    		{
    			cout << arrVec[i][j] << "\t";
    		}
    		cout << endl;
    	}
    }
    
    int main() 
    {
    	testArrayVsArray();
    	testVectorVsVector();
    	testArrayVsVector();
    	testVectorVsArray();
    	return 0;
    }

    双向链表

  • list

    #include <list>
    #include <iostream>
    #include <string>
    #include <functional>  //less和greator头文件
    using namespace std;
    list<int>::iterator myFind(list<int>& iNum,int data) 
    {
    	for (list<int>::iterator iter = iNum.begin(); iter != iNum.end(); iter++) 
    	{
    		if (*iter == data) 
    		{
    			return iter;
    		}
    	}
    	return iNum.end();
    }
    //基本操作: 操作基本数据类型
    void testList() 
    {
    	list<int> iNum;
    	list<string> strNum;
    	//插入
    	strNum.push_back("string1");	//尾插发
    	strNum.push_back("string2");
    	strNum.push_front("string3");
    	//string3 string1  string2
    	//遍历
    	//不删除方式遍历
    	list<string>::iterator iter;
    	for (iter = strNum.begin(); iter != strNum.end(); iter++) 
    	{
    		cout << *iter << " ";
    	}
    	cout << endl;
    	cout << "是否为空:" <<boolalpha<< !strNum.empty() << endl;
    	cout << "元素个数:" << strNum.size() << endl;
    	//删除方式遍历
    	//string3 string1  string2
    	while (!strNum.empty()) 
    	{
    		cout << strNum.front() << " ";	//back()
    		strNum.pop_front();				//头部删除  pop_front();
    	}
    	cout << endl;
    	cout << "元素个数:" << strNum.size() << endl;
    	//指定位置操作
    	//iterator find(iterator begin,iterator end,data);
    	for (int i = 0; i < 3; i++) 
    	{
    		iNum.push_back(i);
    	}
    	auto result = find(iNum.begin(), iNum.end(), 2);
    	//没找到返回是end结束的位置
    	if (result == iNum.end()) 
    	{
    		cout << "未找到指定位置" << endl;
    	}	//insert
    	iNum.insert(result, 100);
    	for (auto v : iNum) 
    	{
    		cout << v << "\t";
    	}
    	cout << endl;
    	//删除函数
    	iNum.erase(result);
    	for (auto v : iNum)
    	{
    		cout << v << "\t";
    	}
    	cout << endl;
    	//其他操作
    	iNum.reverse();				//反转链表
    	for (auto v : iNum)
    	{
    		cout << v << "\t";
    	}
    	cout << endl;
    	iNum.sort(less<int>());				//排序
    	for (auto v : iNum)
    	{
    		cout << v << "\t";
    	}
    	cout << endl;
    }
    void testDelete() 
    {
    	int array[4] = { 1,2,2,3 };
    	list<int> data;
    	data.assign(array, array + 4);
    	//相同元素的删除
    	for (list<int>::iterator iter = data.begin(); iter != data.end(); )
    	{
    		if (*iter == 2)
    		{
    			iter = data.erase(iter);
    		}
    		else
    		{
    			iter++;
    		}
    	}
    	for (auto v : data)
    	{
    		cout << v << "\t";
    	}
    	cout << endl;
    }
    //操作自定义类型数据
    class MM 
    {
    public:
    	MM(string name, int age, int num) :name(name), age(age), num(num) {}
    	void print() 
    	{
    		cout << name << "\t" << age << "\t" << num << endl;
    	}
    	bool operator==(const string& name) const
    	{
    		return this->name == name;
    	}
    	bool operator<(const MM& object) const 
    	{
    		return this->name < object.name;
    	}
    	string getName() const
    	{
    		return name;
    	}
    	int getAge() const
    	{
    		return age;
    	}
    protected:
    	string name;
    	int age;
    	int num;
    };
    bool compareByName(const MM& object1, const MM& object2) 
    {
    	return object1.getName() < object2.getName();
    }
    bool compareByAge(const MM& object1, const MM& object2)
    {
    	return object1.getAge() < object2.getAge();
    }
    void testUserData() 
    {
    	list<MM> mmData;
    	string name;
    	int age;
    	int num;
    	while (1) 
    	{
    		cout << "input MM:" << endl;
    		cin >> name >> age >> num;
    		mmData.push_back(MM(name, age, num));
    		cout << "是否继续输入?" << endl;
    		while (cin.get() != '\n');
    		if (cin.get() == 'n')
    			break;
    	}
    	cout << "姓名\t年龄\t编号" << endl;
    	for (MM v : mmData) 
    	{
    		v.print();
    	}
    	//二进制“==”: 没有找到接受“MM”类型的左操作数的运算符(或没有可接受的转换)
    	auto result = find(mmData.begin(), mmData.end(), string("name1"));
    	//重载方式
    	mmData.sort(less<MM>());		//重载<  
    	//mmData.sort(greater<MM>());	//重载>
    	//不采用重载方式,需要自己写比较准则
    	mmData.sort(compareByName);
    	mmData.sort(compareByAge);
    }
    int main() 
    {
    	//testList();
    	//testDelete();
    	testUserData();
    	return 0;
    }

  • stack

    #include <stack>
    #include <iostream>
    #include <string>
    using namespace std;
    void testStack() 
    {
    	//穿脱原则
    	//FILO  
    	//1 2 3 
    	//3 2 1 
    	//push(data)
    	//pop()  删除
    	//top()  获取栈顶元素
    	//size() empty();
    	stack<int> intStack;
    	for (int i = 0; i < 3; i++) 
    	{
    		intStack.push(i);
    	}
    	while (!intStack.empty()) 
    	{
    		cout << intStack.top() << "\t";
    		intStack.pop();
    	}
    	cout << endl;
    }
    
    void NumTobinary(int data) 
    {
    	stack<int> bin;
    	while (data) 
    	{
    		bin.push(data % 2);
    		data = data / 2;
    	}
    	if (bin.size() < 8) 
    	{
    		for (int i = bin.size(); i < 8; i++) 
    		{
    			bin.push(0);
    		}
    	}
    	while (!bin.empty()) 
    	{
    		cout << bin.top();
    		bin.pop();
    	}
    	cout << endl;
    	//中缀和后缀表达式资料看看
    	//a+b 中缀
    	//ab+
    	//a+b*c+d;
    }
    int main() 
    {
    	//testStack();
    	NumTobinary(512);
    	return 0;
    }

    队列

  • queue

    #include <queue>
    #include <iostream>
    #include <string>
    using namespace std;
    void pop_queue(queue<int> qData) 
    {
    	while (!qData.empty())
    	{
    		cout << qData.front() << " ";  //获取队头元素
    		qData.pop();	//出队
    	}
    	cout << endl;
    }
    void testQueue() 
    {
    	queue<int> qData;
    	for (int i = 0; i < 3; i++) 
    	{
    		qData.push(i);	//入队
    	}
    	while (!qData.empty()) 
    	{
    		cout << qData.front() << " ";  //获取队头元素
    		qData.pop();	//出队
    	}
    	cout << endl;
    	cout << qData.size() << endl;
    }
    int main() 
    {
    	testQueue();
    
    
    	return 0;
    }

    deque

    #include <deque>
    #include <iostream>
    #include <string>
    using namespace std;
    //从头出来
    void pop_front_dequeue(deque<int> dData) 
    {
    	while (!dData.empty()) 
    	{
    		cout << dData.front()<<" ";
    		dData.pop_front();
    	}
    	cout << endl;
    }
    //从尾出来
    void pop_back_dequeue(deque<int> dData)
    {
    	while (!dData.empty())
    	{
    		cout << dData.back() << " ";
    		dData.pop_back();
    	}
    	cout << endl;
    }
    void testDeque() 
    {
    	deque<int> deData;
    	for (int i = 0; i < 3; i++) 
    	{
    		deData.push_back(i);		//尾插法入队
    		deData.push_front(i);		//头插法入队
    	}
    	deData.push_back(999);
    	//0 0
    	//1 0 0 1
    	//2 1 0 0 1 2
    	pop_front_dequeue(deData);
    	pop_back_dequeue(deData);
    }
    int main() 
    {
    	testDeque();
    	return 0;
    }

    priority_queue

    #include <iostream>
    #include <queue>
    #include <vector>
    using namespace std;
    template <class _Ty,class _Container = vector<_Ty>,class _Pr = less<_Ty>>
    class my_priority_queue
    {
    public:
    
    protected:
    
    };
    void testCreatePriorityQueue() 
    {
    	//默认的方式,一级下面三种 都一样,大的先出队
    	priority_queue<int> pqData;
    	priority_queue<int,vector<int>> pqData2;			//默认排序准则
    	priority_queue<int,vector<int>,less<int>> pqData3;	//所有参数都完整
    	//优先队列,是按照数据的优先权出队,VIP服务
    	pqData.push(12);
    	pqData.push(0);
    	pqData.push(34);
    	while (!pqData.empty()) 
    	{
    		cout << pqData.top()<<" ";
    		pqData.pop();		//出队
    	}
    	cout << endl;
    	//贪心算法
    	priority_queue<int, vector<int>, greater<int>> pqDataG;	
    	pqDataG.push(12);
    	pqDataG.push(0);
    	pqDataG.push(34);
    	while (!pqDataG.empty())
    	{
    		cout << pqDataG.top() << " ";
    		pqDataG.pop();		//出队
    	}
    	cout << endl;
    }
    int main() 
    {
    	testCreatePriorityQueue();
    	return 0;
    }

    集合

  • set/multiset

    #include <set>
    #include <iostream>
    #include <ctime>
    using namespace std;
    /*
    	set:集合
    	1.数据自带排序
    	2.数据唯一性
    */
    class MM 
    {
    public:
    	MM(string name, int age) :name(name), age(age) {}
    	bool operator<(const MM& object)const 
    	{
    		return this->name < object.name;
    	}
    	void print() 
    	{
    		cout << name << " " << age << endl;
    	}
    protected:
    	string name;
    	int age;
    };
    
    void testSet() 
    {
    	srand((unsigned int)time(nullptr));
    	set<int> setData;					//默认方式 从小到大
    	set<int, less<int>> setData2;		//和默认方式一样
    	set<int, greater<int>> setData3;	//从大到小
    	int array[10] = { 0 };
    	for (int i = 0; i < 10; i++)
    	{
    		int temp = rand() % 10;
    		array[i] = temp;
    		setData.insert(temp);
    	}
    	for (auto v : array) 
    	{
    		cout << v << " ";
    	}
    	cout << endl;
    	for (set<int>::iterator iter = setData.begin(); iter != setData.end(); iter++) 
    	{
    		cout << *iter << " ";
    	}
    	cout << endl;
    }
    void testUserData() 
    {
    	set<MM> mmData;   //less<int> <
    	mmData.insert(MM("name3", 19));
    	mmData.insert(MM("name2", 28));
    	mmData.insert(MM("name3", 188));
    	for (auto v : mmData) 
    	{
    		v.print();
    	}
    
    	set<char> cData;
    	set<string> strData;
    }
    //多重集合: 只具有排序功能,不具有去重功能
    void testmultiset()
    {
    	multiset<int> mulData;
    	for (int i = 0; i < 10; i++) 
    	{
    		mulData.insert(rand() % 10);
    		//rand()%26+'A';
    		//rand()%26+'a';
    	}
    	for (auto v : mulData) 
    	{
    		cout << v << " ";
    	}
    	cout << endl;
    }
    int main() 
    {
    	testSet();
    	testUserData();
    	testmultiset();
    
    
    	return 0;
    }

    bitset

    #include <iostream>
    #include <bitset>
    using namespace std;
    template <class _Ty,size_t size>
    class MyArray 
    {
    
    };
    int main() 
    {
    	//多个二进制位
    	bitset<8> bData("11110000");
    	cout << bData << endl;
    	bData.flip();
    	cout << bData << endl;
    	cout << bData.all() << endl;
    	cout << bData.any() << endl;
    	cout << bData.size() << endl;
    	cout <<bData.none() << endl;
    	bitset<8> num(7);
    	cout << num << endl;
    	return 0;
    }

    映射

  • map/multiset

    #include <map>
    #include <iostream>
    #include <graphics.h>
    using namespace std;
    template <class _Ty1, class _Ty2>
    struct MyPair 
    {
    	_Ty1 first;
    	_Ty2 second;
    	MyPair(_Ty1 first, _Ty2 second) :first(first), second(second) {}
    };
    //map存储的数据是一个数对类型
    void testPair() 
    {
    	pair<int, string> pData(1, "string");
    	MyPair<int, string> myPData(1, "string");
    	cout << pData.first << " " << pData.second << endl;
    }
    //map
    //1.自带排序,默认是从小到大
    //2.数据唯一性
    void testMap() 
    {
    	map<int, string> mapData;
    	map<int, string, less<int>> mapData1; //和上面创建方式一样,从小到大
    	map<int, string, greater<int>> mapData2; //从大到小
    	//1.insert插入
    	mapData.insert(pair<int, string>(1, "string"));
    	//2.make_pair构建数对插入
    	mapData.insert(make_pair<int, string>(3, "string3"));
    	//3.单映射,可以直接采用数组下标方式进行插入
    	//数组在一定程序上来说或可以说数组
    	//map[first]=second;
    	//相比数组来说,这个下标是没有任何要求
    	mapData[-1] = string("string-1");  //等效插入一个数对类型
    	//上面代码等效:mapData.insert(pair<int,string>(-1,"string-1"))
    	mapData[1] = "string1";		//相同键 采用的是覆盖方式
    	//遍历:
    	for (auto iter = mapData.begin(); iter != mapData.end(); iter++) 
    	{
    		//*iter指的是pair类型
    		cout << iter->first << " " << iter->second<<endl;
    	}
    	for (auto v : mapData) 
    	{
    		cout << v.first << "\t" << v.second << endl;
    	}
    	//map<string, IMAGE*> img;
    	//img["墙"] = new IMAGE;
    	//img["路"] = new IMAGE;
    	//putimage(0, 0, img["墙"]);
    	//putimage(0, 0, img["路"]);
    	cout << mapData[1] << endl;    //用的时候直接使用即可
    	mapData.erase(1);
    	for (auto v : mapData)
    	{
    		cout << v.first << "\t" << v.second << endl;
    	}
    	cout << endl;
    }
    class MM
    {
    public:
    	MM() = default;
    	MM(string name, int age) :name(name), age(age) {}
    	void print() const
    	{
    		cout << name << "\t" << age << endl;
    	}
    	bool operator<(const MM& object)const 
    	{
    		return this->name < object.name;
    	}
    protected:
    	string name;
    	int age;
    };
    class Boy
    {
    public:
    	Boy() = default;
    	Boy(string name, int age) :name(name), age(age) {}
    	void print() const
    	{
    		cout << name << "\t" << age << endl;
    	}
    protected:
    	string name;
    	int age;
    };
    void testUserData() 
    {
    	map<MM, Boy> mbData;
    	mbData[MM("小美", 19)] = Boy("小张", 29);
    	mbData[MM("小美", 19)].print();
    	mbData[MM("小丽", 20)] = Boy("小明", 18);
    	cout << "配对信息:" << endl;
    	for (auto v : mbData) 
    	{
    		//容器管理自定义类型数据
    		//v:pair<MM,Boy>
    		//v.frist:MM
    		//v.second:Boy
    		v.first.print();
    		v.second.print();
    	}
    }
    void testmultimap() 
    {
    	//多重映射,没有什么限制,什么样对应关系都可以插入到映射中
    	//因为存在相同的键,所以不能采用下标法
    	multimap<int, string>  mulData;
    	mulData.insert(pair<int, string>(1, "string"));
    	mulData.insert(pair<int, string>(1, "string1"));
    	mulData.insert(pair<int, string>(2, "string"));
    	mulData.insert(pair<int, string>(3, "string"));
    	mulData.insert(make_pair<int, string>(3, "string"));
    	for (auto v : mulData) 
    	{
    		cout << v.first << "\t" << v.second << endl;
    	}
    }
    int main() 
    {
    	testMap();
    	testUserData();
    	testmultimap();
    	return 0;
    }

    列表

  • initializer_list

    #include <array>
    #include <list>
    #include <vector>
    #include <iostream>
    #include <initializer_list>
    using namespace std;
    class MM 
    {
    public:
    	MM(string a, string b, string c) :a(a), b(b), c(c) {}
    	MM(const initializer_list<string>& list) 
    	{
    		for (auto iter = list.begin(); iter != list.end(); iter++) 
    		{
    			cout << *iter << endl;
    		}
    	}
    protected:
    	string a;
    	string b;
    	string c;
    };
    void print(initializer_list<int> list) 
    {
    	for (auto iter = list.begin(); iter != list.end(); iter++)
    	{
    		cout << *iter << " ";
    	}
    	cout << endl;
    }
    
    int main()
    {
    	array<int, 3> arrData = { 1,2,3 };
    	vector<int> vecData1 = { 1,2,3,4 };
    	vector<int> vecData2 = { 1,2,3,4,5 };
    	MM mm1 = { "string1","string2","string3" };
    	MM mm2 = { "string1" };
    	MM mm3 = { "string1","string2" };
    	initializer_list<int> listOne = { 1,2,3,4,5 };
    	initializer_list<int> listTwo = { 1,2,3};
    	print({ 1 });
    	print({ 1,2 });
    	print({ 1,2,3,4 });
    	print({ 1,2,3,4,5 });
    	return 0;
    }

    元组

  • tuple

    #include <tuple>
    #include <iostream>
    using namespace std;
    void testTuple()
    {
    	//把任何类型的一系列数据当做一组处理
    	tuple<string, int, int, string> mmInfo = {"MM",18,1001,"123445"};
    	tuple<double, double, double> mmscore = make_tuple(98, 98, 88);
    	tuple<string, string> value = forward_as_tuple("小张", "小美");
    	tuple<string, int, int, string> array[3];
    }
    void visitedData() 
    {
    	tuple<string, int, int, string> mmInfo = { "MM",18,1001,"123445" };
    	//get方法,不能用for循环
    	cout << get<0>(mmInfo) << "\t";
    	cout << get<1>(mmInfo) << "\t";
    	cout << get<2>(mmInfo) << "\t";
    	cout << get<3>(mmInfo) << endl;
    	//tie的方式访问数据
    	string name;
    	int age;
    	int num;
    	string tel;
    	tie(name, age, num, tel) = mmInfo;
    	cout << name << "\t" << age << "\t" << num << "\t" << tel << endl;
    }
    void Exoperator() 
    {
    	tuple<string, int, int, string> mmInfo = { "MM",18,1001,"123445" };
    	tuple<double, double, double> mmscore = make_tuple(98, 98, 88);
    	auto result = tuple_cat(mmInfo, mmscore);
    }
    int main() 
    {
    
    	visitedData();
    	return 0;
    }

    C++STL迭代器

    迭代器

  • 迭代器: 就是一个类中类,通过运算符重载通过类中类的对象去遍历容器

  • 迭代器的分类

    • 正向迭代器: iterator

      • begin();

      • end();

    • 反向迭代器: reverse_iterator

      • rbegin();

      • rend();

    • 常正向迭代器: const_iterator

      • cbegin();

      • cend();

    • 常反向迭代器:const_reverse_iterator

      • crbegin();

      • crend();

  • Lambda: 就是一个返回函数指针的表达式,它定义和返回值函数指针在一起的

  • Lambda表达式的组成部分

  • 按功能分类

    • 正向迭代

    • 双向迭代

    • 随机访问迭代器

  • 容器中迭代器分类

    容器名迭代器类型
    array随机访问
    vector随机访问
    deque随机访问
    stack/queue/priority_queue(特定顺序存取)不支持
    list双向
    set/multiset双向
    map/multimap双向
  • 迭代器辅助函数

    • 移动:advance(iterator iter,n);

    • 间距:distance(iterator begin,iterator end);

    • 交换:iter_swap(iterato first,iterator end);

  • 拓展内容:特殊迭代器 流型迭代器-->一般用在辅助打印

    • 输出流型

      • ostream_iterator<_Ty> iter(ostream& out);

      • ostream_iterator<_Ty> iter(ostream& out,char* str);

      • 输出流型迭代做赋值运算,意味着就是打印数据到屏幕上

    • 输入流型

      • istream_iterator<_Ty> iter; //构造无参对象,是一个错误流 end_of_ostream

      • istream_iterator<_Ty> iter(istream& in);

      • *iter 等效cin>>操作

      • Lambda表达式

      • Lambda: 就是一个返回函数指针的表达式,它定义和返回值函数指针在一起的

      • Lambda表达式的组成部分

        // [捕获方式](函数参数)mutable exception->函数返回值类型{函数体;}
        int Max(int a,int b)
        {
            return a>b?a:b;
        }
        void print()
        {
            //Max的Lambda表达式写法
        	int(*pMax)(int,int)=[](int a,int b)mutable noexcept->int{ return a>b?a:b;};  
            //省略写法: 中间描述此都可以省略
            auto ppMax=[](int a,int b){reutrn a>b?a:b;};
        }
        //捕获方式-->函数使用外部的变量的方式
        /*
        	[=]   //值的方式捕获
        	[&]	  //引用的方式捕获
        	[this]//this指针方式捕获
        	[]    //不捕获任何变量
        	[=,&x];//x用引用方式捕获,其他变量用值的方式捕获
        */
        #include <iostream>
        using namespace std;
        int Max(int a, int b) 
        {
        	return a > b ? a : b;
        }
        void print(int(*pMax)(int, int), int a, int b) 
        {
        	cout << pMax(a, b) << endl;
        }
        class MM 
        {
        public:
        	void print() 
        	{
        		[this] {cout << name << "\t" << age << endl; }();		//定义和调用一步到位
        	}
        protected:
        	string name="默认";
        	int age=100;
        };
        int main() 
        {
        	int(*pMax)(int, int) = nullptr;
        	//完整版:Lambad 表达式
        	//final override
        	pMax = [](int a, int b)mutable noexcept->int {return a > b ? a : b; };
        	cout << pMax(1, 3) << endl;
        	//省略版本的,写代码越简单越好
        	auto  pp = [](int a, int b) {return a > b ? a : b; };
        	cout << pp(1, 3) << endl;
        	//实际使用可以一步到位--->短暂性局部使用的的函数
        	cout << [](int a, int b)mutable noexcept->int {return a > b ? a : b; }(1, 3) << endl;
        	print([](int a, int b) {return a > b ? a : b; }, 1, 3);
        	print([](int a, int b) {return a > b ? b : a; }, 1, 3);
        	print([](int a, int b) {return a+b; }, 1, 3);
        	//捕获方式的区别
        	//用值的捕获: 在Lambad中不能把值当做左值使用,函数调用不会因为值的改变而改变
        	int data = 101010;
        	auto pFunc = [=] {  cout << data << endl; };  //无参() 可以省略
        	auto pFunc2 = [&] { cout << data << endl; };
        	pFunc();
        	pFunc2();
        	data = 808080;
        	pFunc();
        	pFunc2();
        	MM  mm;
        	mm.print();
        	//特殊的东西-->结合auto使用
        	auto pAuto = [](auto a, auto b) ->auto{return a > b ? a : b; };
        	cout << pAuto(1, 3) << endl;				//[](auto a, auto b) ->auto{return a > b ? a : b; }(1,3)
        	cout << pAuto("stringa", "stringb") << endl;
        	//[] (auto a, auto b) ->auto{return a > b ? a : b; }("stringa", "stringb");
        	return 0;
        }

        仿函数

      • 什么仿函数? 类模仿函数调用行为,实质是无名对象调用重载的()函数

        • 所以仿函数的关键点在于重载()

      • 一般情况仿函数是做排序准则,或者一些算法的计算准则

      • 标准库中的仿函数

        • 算术类

        • 关系类

        • 逻辑类

        • 选择,证同,投射

          #include <iostream>
          #include <string>
          #include <functional>		//仿函数所在头文件
          #include <map>
          using namespace std;
          class Sum 
          {
          public:
          	int  operator()(int a, int b) const 
          	{
          		return a + b;
          	}
          };
          int main()
          {
          	//重载的()的调用方式
          	Sum s;
          	cout << "显式调用:" << s.operator()(1, 3) << endl;		//显式调用重载函数
          	cout << "隐式调用:" << s(1, 3) << endl;
          	//用{}和()帮助编译器去做解析
          	cout << "无名调用:" << Sum{}(1, 3) << endl;			//类模仿函数调用行为--->仿函数
          	cout << "无名调用:" << Sum()(1, 3) << endl;			//类模仿函数调用行为--->仿函数
          	//算术
          	cout << plus<int>{}(1, 3) << endl;
          	//关系
          	cout << equal_to<int>{}(1, 3) << endl;
          	map<int, less<int>> map1;
          	map<int, greater<int>> map3;
          	//逻辑类
          	cout << logical_and<int>{}(1,0) << endl;
          	//求大于3 小于10的数字
          	//没必要的做的事情
          	int a = 34;
          	if (logical_and<int>{}(a > 3, a < 10)) 
          	{
          		cout << "大于3 小于10的数字" << endl;
          	}
          
          	return 0;
          }

          函数适配器

        • 什么是函数适配器: 用来绑定函数调用时候的参数,让函数适应其他调用的用法

          #include <iostream>
          #include <string>
          #include <functional>
          #include <vector>
          #include <algorithm>
          using namespace std;
          //老版本bind1st bind2nd
          //新版本: bind函数
          int Max(int a, int b) 
          {
          	return a > b ? a : b;
          }
          void print(int(*pMax)(int,int), int a,int b) 
          {
          	cout << pMax(a,b) << endl;
          }
          class Test 
          {
          public:
          	void print(int a, int b, int c) 
          	{
          		cout << a << " " << b << " " << c << endl;
          	}
          protected:
          };
          void testClassFunc()
          {
          	Test test;
          	auto testFunc = bind(&Test::print, &test, std::placeholders::_1, std::placeholders::_2, 99);
          	testFunc(1, 3);		//调用,直接调用
          }
          
          void printData(int one, Test two, string str) 
          {
          	cout << "调用成功" << endl;
          }
          //可以通过占位符,所以调整参数位置,形成不同的调用形态
          void testExUser() 
          {
          	//占位符代表原函数的参数 在调用形态 的第二个位置
          	auto testFunc = bind(printData,std::placeholders::_3, std::placeholders::_1, std::placeholders::_2);
          	printData(1, Test(), "ILoveyou");
          	testFunc(Test(), "ILoveyou", 1);
          }
          
          int main() 
          {
          	cout << Max(1, 3) << endl;
          	//基本用法
          	//std::placeholders::_1占位符
          	auto pMax = bind(Max, std::placeholders::_1, 100);  //把第二个参数置为100
          	//只是增加调用行为,并没有真正改变了这个函数指针类型
          	cout << pMax(34) << endl;
          	cout << pMax(13, 44) << endl;  //绑定后的函数指针,不再支持传参的,第二个参数无效
          	//语法上没问题,但是尽量别这样做
          	using namespace std::placeholders;
          	auto pMax2 = bind(Max, _1, 100);  //把第二个参数置为100
          	cout << pMax2(34) << endl;
          	vector<int> vecData = { 19,43,89,89,34,54,67,54 };
          	cout << count_if(vecData.begin(), vecData.end(),bind(greater<int>(),std::placeholders::_1,60)) << endl;
          	cout << count_if(vecData.begin(), vecData.end(), [](int a) {return a > 60; }) << endl;
          	testClassFunc();
          	testExUser();
          
          	return 0;
          }

          函数包装器

        • 函数包装器是什么?就是把函数指针包装成一个对象。通过这个对象调用函数

          • 一旦函数指针被函数包装器包装了,那这个包装器对象可以直接替换函数指针的用法去调用函数

        • 函数包装器类的实力例化传参: function<函数返回值类型(参数类型)>

          #include <iostream>
          #include <string>
          #include <functional>
          using namespace std;
          int Max(int a, int b) 
          {
          	cout << "包装普通函数:" << endl;
          	return a > b ? a : b;
          }
          class MM 
          {
          public:
          	void print(int a)    //void print(int a, MM* mm);
          	{
          		cout << "包装成员函数" << endl;
          	}
          	static void printStatic() 
          	{
          		cout << "包装静态的函数" << endl;
          	}
          protected:
          };
          void testMMFunc() 
          {
          	MM mm;
          	function<void(int)> func(bind(&MM::print,&mm,std::placeholders::_1));
          	func(12);
          }
          
          
          class Test 
          {
          public:
          	void operator()(string str) 
          	{
          		cout << str << endl;
          	}
          };
          
          
          
          
          void printData(int a, MM mm, string str) 
          {
          	cout << "bind和function" << endl;
          }
          void TestFuncBind() 
          {
          	function<void(string, int, MM)> pf = bind(printData,
          		std::placeholders::_2, std::placeholders::_3, std::placeholders::_1 );
          	pf("string", 1, MM());
          	//3  1  2
          }
          
          int main() 
          {
          	function<int(int, int)> funcMax(Max);
          	cout << funcMax(1, 3) << endl;
          
          	function<int(int, int)> funcMax2=Max;
          	function<void()> funcS(MM::printStatic);
          	funcS();
          
          	//仿函数包装
          	Test test;
          	function<void(string)> func = test;
          	func("包装仿函数");
          	TestFuncBind();
          	//包装成员函数
          	testMMFunc();
          	return 0;
          }

          C++STL算法篇

          STL查找算法

        • 基本查找

          • find:区间查找

          • find_if:条件查找

          • find_firt_of: 查找区间第一次出现值

          • adjacent_find: 查找第一次重复的数

          • search:子序列查找

          • search_n: 子序列查找出现次数

        • 统计查找

          • count: 区间统计

          • count_if: 条件统计个数

          • equal:比较

        • 有序查找

          • binary_search:二分查找

          • upper_bound: 查找最后一个大于查找的值

          • lower_bound: 大于等于查找的值

          • equal_range:区间比较---有序序列

        • STL排序通用算法

        • merge: 归并排序,存于新容器

        • inplace_merge: 归并排序,覆盖原区间

        • sort: 排序,更改原容器顺序

        • stable_sort: 排序,保存原容器数据顺序

        • nth_element: 关键字排序

        • partition:范围排序

        • partial_sort:范围排序

        • partial_sort_copy:范围排序外加复制操作

        • stable_partition: 范围排序,保存原容器顺序

        • random_shuffle: 随机排序

        • reverse:逆序原容器

        • reverse_copy: 逆序容器保存到新容器

        • STL删除替换算法

        • copy: 拷贝函数

        • copy_backward: 逆序拷贝

        • iter_swap: 交换

        • remove: 删除

        • remove_copy: 删除元素复制到新容器

        • remove_if:条件删除

        • remove_copy_if:条件删除拷贝到新容器

        • replace:替换

        • replace_copy: 替换,结果放到新容器

        • replace_if: 条件替换

        • replace_copy_if:条件替换,结果另存

        • swap: 交换

        • swap_range:区间交换

        • unique:去重

        • unique_copy:去重,结果另存

        • STL排列组合算法

        • next_permutation:下一个排序序列的组合

        • prev_permutation:上一个排序序列的组合

        • STL 算术算法

        • accumulate:区间求和

        • partial_sum:相邻元素的和

        • inner_product:序列内积运算

        • adjacent_difference:相邻元素的差

        • STL 生成异变算法

        • for_each:迭代访问

        • fill:填充方式初始容器

        • fill_n:指定长度填充容器

        • generate_n:填充前n个位置

        • transform:一元转换和二元转换

        • STL 关系算法

        • equal:两容器元素是否都相同

        • includes:是否是包含关系

        • lexicographical_compare:比较两个序列

        • max:求最大值

        • max_element:返回最大值的iterator

        • min:求最小值

        • min_element:求最小值的iterator

        • mismatch:找到第一个不同的位置

        • STL 集合算法

        • set_union:差集

        • set_intersection:并集

        • set_difference:保存第一个中有第二个没有的元素

        • set_symmetric_difference:对称差集

        • STL堆算法

        • make_heap:生成一个堆

        • pop_heap:出堆

        • push_heap:入堆

        • sort_heap:堆排序

        • rotate:移动元素到容器末尾

        • rotate_copy:移动元素到新容器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值