Solutions to common function usage of vector and iterator failure in STL [C++]

size && capacity

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    
    
	vector<int> v(10, 2);
	cout << v.size() << endl; //获取当前容器中的有效元素个数
	cout << v.capacity() << endl; //获取当前容器的最大容量
	return 0;
}

reserve

Change the capacity of the container through the reserse function

1. When the given value is greater than the current capacity of the container, expand the capacity to this value.
2. When the given value is less than the current capacity of the container, do nothing.

resize

The resize function changes the number of valid elements in the container, that is, size

1. When the given value is greater than the current size of the container, expand the size to this value, and the expanded element is the second given value. If not given, it defaults to 0.
 2. When the given value is smaller than the current size of the container, reduce the size to this value.

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    
    
	vector<int> v(10, 2);
	cout << v.size() << endl; //10
	cout << v.capacity() << endl; //10
	v.reserve(20); //改变容器的capacity为20,size不变
	cout << v.size() << endl; //10
	cout << v.capacity() << endl; //20
	v.resize(15); //改变容器的size为15
	cout << v.size() << endl; //15
	cout << v.capacity() << endl; //20
	return 0;
}

empty

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    
    
	vector<int> v(10, 2);
	cout << v.empty() << endl;
	return 0;
}

iterator

begin and end

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    
    
	vector<int> v(10, 2);
	//正向迭代器遍历容器
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
    
    
		cout << *it << " ";
		it++;
	}
	cout << endl;
	return 0;
}

insert image description here
A reverse iterator iterates over a container:

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    
    
	vector<int> v(10, 2);
	//反向迭代器遍历容器
	vector<int>::reverse_iterator rit = v.rbegin();
	while (rit != v.rend())
	{
    
    
		cout << *rit << " ";
		rit++;
	}
	cout << endl;
	return 0;
}

push_back &&pop_back

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    
    
	vector<int> v;
	v.push_back(1); 
	v.push_back(2);
	v.push_back(3); 
	v.push_back(4);

	v.pop_back();
	v.pop_back(); 
	v.pop_back(); 
	v.pop_back(); 
	return 0;
}

insert && erase

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    
    
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.insert(v.begin(), 0); //在容器开头插入0
	
	v.insert(v.begin(), 5, -1); //在容器开头插入5个-1

	v.erase(v.begin()); //删除容器中的第一个元素

	v.erase(v.begin(), v.begin() + 5); //删除在该迭代器区间内的元素(左闭右开)
	
	return 0;
}

find

The find function is implemented in the algorithm module (algorithm), not a member function of vector

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    
    
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	
	vector<int>::iterator pos = find(v.begin(), v.end(), 2); //左闭右开
	//auto pos =find(v.begin()  , v.end() , 2) ;
	v.insert(pos, 10); //在2的位置插入10
    //左闭右开
	pos = find(v.begin(), v.end(), 3); //获取值为3的元素的迭代器
	
	v.erase(pos); //删除3

	return 0;
}

swap

The data space of the two containers can be exchanged through the swap function to realize the exchange of the two containers.

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    
    
	vector<int> v1(10, 1);
	vector<int> v2(10, 2);

	v1.swap(v2); //交换v1,v2的数据空间

	return 0;
}

[ ]

The overloading of the [] operator is implemented in vector

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    
    
	vector<int> v(10, 1);
	//使用“下标+[]”的方式遍历容器
	for (size_t i = 0; i < v.size(); i++)
	{
    
    
		cout << v[i] << " ";
	}
	cout << endl;
	return 0;
}

Range for iterates over vector

Use the range for to traverse the vector container. (Supporting iterators supports range for, and the compiler will automatically replace range for with iterators at compile time)

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    
    
	vector<int> v(10, 1);
	//范围for
	for (auto e : v)
	{
    
    
		cout << e << " ";
	}
	cout << endl;
	return 0;
}

Iterator invalidation problem

The main function of the iterator is to allow the algorithm to not care about the underlying data structure. The underlying data structure is actually a pointer, or a pointer is encapsulated. For example, the iterator of vector is the original ecological pointer T*. Therefore, the invalidation of the iterator actually means that the space pointed to by the corresponding pointer at the bottom of the iterator is destroyed, and a piece of space that has been released is used, resulting in a program crash (that is, if you continue to use the invalid iterator, the program may crash. ).

one,

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main()
{
    
    
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	//v: 1 2 3 4 5
	vector<int>::iterator pos = find(v.begin(), v.end(), 2); //获取值为2的元素的迭代器
	//auto pos =find(v.begin(),v.end() ,2);
	v.insert(pos, 10); //在值为2的元素的位置插入10
	//v: 1 10 2 3 4 5
	v.erase(pos); //删除元素2  error(迭代器失效)
	//v: 1 2 3 4 5
	return 0;
}

In this code, we intend to use the iterator of element 2 to insert a 10 at the position of 2 in the original sequence, and then delete 2, but what we actually get is a pointer to 2, when we insert 10 at the position of 2 , the pointer points to 10, so what we delete later is actually 10, not 2

Solution: The iterator is invalid. Solution: Just reassign the iterator before using it

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main()
{
    
    
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	//v: 1 2 3 4 5
	vector<int>::iterator pos = find(v.begin(), v.end(), 2); //获取值为2的元素的迭代器
	//auto pos =find(v.begin(),v.end() ,2);
	v.insert(pos, 10); //在值为2的元素的位置插入10
	//v: 1 10 2 3 4 5
	pos = find(v.begin(), v.end(), 2); //重新获取值为2的元素的迭代器,(解决迭代器失效,重新赋值即可)
	v.erase(pos); //删除元素2
	//v: 1 10 3 4 5
	return 0;
}

two,

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    
    
	vector<int> v;
	v1.push_back(1);
    v1.push_back(2);
    v1.push_back(2);
    v1.push_back(3);
    v1.push_back(4);
    v1.push_back(5);
    v1.push_back(6);
	vector<int>::iterator it = v.begin();
	//auto it = v.begin();
	while (it != v.end())
	{
    
    
		if (*it % 2 == 0) //删除容器当中的全部偶数
		{
    
    
			v.erase(it);
		}
		it++;
	}
	return 0;
}

insert image description here

Solution : We can receive the return value of the erase function ( the erase function returns the new position of the element after the deleted element ), and control the logic of the code: when the element is deleted, continue to judge the element at this position (because the element at this position has already update, need to judge again).

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    
    
	vector<int> v;
	v1.push_back(1);
    v1.push_back(2);
    v1.push_back(2);
    v1.push_back(3);
    v1.push_back(4);
    v1.push_back(5);
    v1.push_back(6);
	vector<int>::iterator it = v.begin();
	//auto it = v.begin();
	while (it != v.end())
	{
    
    
	       //是偶数
			if (*it % 2 == 0) //删除容器当中的全部偶数
			{
    
    
				it=v.erase(it);//接受erase的返回值
			}
		  //不是偶数
			else
			{
    
    
			
				it++;
			}
	}
	return 0;
}

Summary:
After the erase and insert in the vector, the iterator may become invalid, and this iterator can no longer be accessed. The
access result is undefined.

The following is the test vector code

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
void test_vector1()
{
    
    
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	for (size_t i = 0; i < v.size(); ++i)
	{
    
    
		cout << v[i];
	}
	cout << endl;
	//迭代器访问 
	vector<int> ::iterator it = v.begin();
	//auto it = v.begin();
	while (it != v.end())
	{
    
    
		cout << *it;
		it++;
	}
	cout << endl;
	//范围for 
	for (auto e : v)
	{
    
    
		cout << e;
	}
	
}
void test_vector2()
{
    
    
	
	vector<string> v;
	//第一种方式
	string name1("zhangsan");
		v.push_back(name1);
	
	//第二种方式
		//匿名对象
		v.push_back(string("zhangsan"));
	
	//第三种方式(推荐)
		v.push_back("zhangsan");
	
}
void test_vector3()
{
    
    
	vector<int> v1(10, 1);
	vector<string> v2(10,"***");
	for (auto e : v1)
	{
    
    
		cout << e;
	}
	cout << endl;
	for (auto e : v2)
	{
    
    
		cout << e;
	}
	cout << endl;
	//自己类型的迭代器
	vector<int> v3(v1.begin(), v1.end());
	for (auto e : v3)
	{
    
    
		cout << e;
	}
	cout << endl;
	string str("hello world");
	vector<char> v4 (str.begin(), str.end());
	for (auto e : v4)
	{
    
    
		cout << e;
	}
	cout << endl;

	int a[] = {
    
     16,2,77,29 };
	vector<int> v5(a, a + 4);
	for (auto e : v5)
	{
    
    
		cout << e<<" ";
	}
	cout << endl;
	//升序  less  < 
	//sort(v5.begin(), v5.end());
	//降序   
	/*sort(v5.rbegin(), v5.rend());*/

	for (auto e : v5)
	{
    
    
		cout << e << " ";
	}
	cout << endl;
	//降序 greater > 
	/*greater <int> gt;*/
	//sort(v5.begin(), v5.end(),gt);
	sort(v5.begin(), v5.end(), greater<int>() ); //匿名对象

	for (auto e : v5)
	{
    
    
		cout << e << " ";
	}
	cout << endl;
}
void test_vector4()
{
    
    
	vector<int>  v1;
	cout << v1.max_size() << endl;
	v1.resize(10);
	//这里使用v1.reserve(10)是错的   []重载的实现里面有assert(pos <_size ) 但是此时_size是0;
	for (size_t i = 0; i < 10; i++)
	{
    
    
		v1[i] = i;
	}
	for (auto e : v1)
	{
    
    
		cout << e<<" ";
	}
	cout << endl;

	vector <int> v2;
	v2.reserve(10);
	for (size_t i = 0; i < 10; ++i)
	{
    
    
		v2.push_back(i);
	}
	for (auto e : v2)
	{
    
    
		cout << e << " ";
	}
	cout << endl;
}
void test_vector5()
{
    
    
	int a[] = {
    
     16,2,77,29,3,33,43,3,2,3,3,2 };
	vector<int> v1(a,  a+sizeof(a)/sizeof(int) );
	for (auto e : v1)
	{
    
    
		cout << e << " ";
	}
	cout << endl;
	 头删
	//v1.erase(v1.begin());
	//for (auto e : v1)
	//{
    
    
	//	cout << e << " ";
	//}
	//cout << endl;
	 头插 
	//v1.insert(v1.begin(),16);
	//for (auto e : v1)
	//{
    
    
	//	cout << e << " ";
	//}
	//cout << endl;
	// 删除第3个数据
	//v1.erase(v1.begin() + 2);
	//for (auto e : v1)
	//{
    
    
	//	cout << e << " ";
	//}
	//cout << endl;
	

	// 删除3,但是不知道3在哪个位置,怎么办?
	//使用迭代器
	vector<int>::iterator   pos =  find(v1.begin(), v1.end(), 3);
	//auto pos = find(v1.begin(), v1.end(), 3);
	// 通过查询文档发现, find函数没有找到会return last
	if (pos != v1.end( ))//find找到了3的位置 
	{
    
    
		v1.erase(pos);
	}

	for (auto e : v1)
	{
    
    
		cout << e << " ";
	}
	cout << endl;
	// 删除所有的3 -- 涉及迭代器失效!后面解决

	pos = find(v1.begin(), v1.end(), 3);

	while (pos != v1.end())//pos不能越界
		//删除第一个找到的3,然后继续找3 ,删除一个3,更新一次pos 
	{
    
    
		v1.erase(pos);//删除第一个找到的3
		pos = find(v1.begin(), v1.end(), 3);//删除一个3,更新一次pos 
	}
	for (auto e : v1)
	{
    
    
		cout << e << " ";
	}
	cout << endl;

	/*v1.assign(10, 1);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;*/
}
void test_vector6()
{
    
    
	string str("hello world");
	sort(str.begin(), str.end());
	cout << str << endl;
	int a[] = {
    
     16,2,77,29 };
	sort(a ,a+4);
	for (auto e : a)
	{
    
    
		cout << e << " ";
	}
}
int main()
{
    
    
	//test_vector1();
	//test_vector2();
	//test_vector3();
	//test_vector4();
	test_vector5();
	//test_vector6();

	return 0;
}

If you think this article is helpful to you, you might as well move your fingers to like, collect and forward, and give Xi Ling a big attention. Every support from you will be transformed into the driving force for me to move forward! ! !

Guess you like

Origin blog.csdn.net/qq_73478334/article/details/131934282