[C + +] learning notes [16]

STL [i]

1. Birth of STL and related concepts

💖 be born:

  • For a long time, the software industry has been hoping to build something that can be reused
  • The object-oriented and generic programming idea of C + + aims to improve the reusability
  • In most cases, data structures and algorithms fail to have a set of standards, resulting in a lot of repetitive work
  • In order to establish a set of standards for data structures and algorithms, there is STL

💖 Basic concepts:

  • STL is broadly divided into container, algorithm and iterator
  • Containers and algorithms are seamlessly connected through iterators
  • Almost all STL code uses template classes or template functions

💖 STL six components:

  • Container: various data structures, such as vector, list, deque, map, etc., are used to store data
  • Algorithm: various common algorithms
  • Iterators: act as glue between containers and algorithms
  • Imitative function: it behaves like a function and can be used as a strategy of the algorithm
  • Adapter: something used to decorate a container or an interface to an emulator or iterator
  • Space configurator: responsible for space configuration and management

💖 Containers can be divided into:

  • Sequential container: it emphasizes the sorting of values. Each element in the sequential container has a fixed position
  • Associative container: a binary tree structure in which there is no strict physical order between the elements

💖 The algorithm is divided into:

  • Qualitative change algorithm: the contents of elements in the interval will be changed during operation
  • Non qualitative algorithm: the element content in the interval will not be changed during the operation

💖 Iterator type:

  • Input iterator, output iterator, forward iterator, bidirectional iterator, random access iterator
  • The commonly used iterators are bidirectional iterators and random access iterators.

2,vector

Basic concepts of vector

Function:

  • vector data structure is very similar to array, also known as single ended array

The difference between vector and ordinary array:

  • The difference is that the array is a static space, while the vector can be extended dynamically

Dynamic expansion:

  • Dynamic expansion is not to continue the new space after the original space, but to find a larger memory space, then copy the original array to the new space, and then release the original space.
  • The iterator of the vector container is an iterator that supports random access

Exercise of storing built-in data types in vector:

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

//The vector container holds built-in data types

void myPrint(int val)
{
	cout << val << endl;
}

void test01()
{
	//Create vector container
	vector<int> v;

	//Insert data into container
	v.push_back(10);
	v.push_back(20);
	v.push_back(30);
	v.push_back(40);
	v.push_back(50);

	//Accessing data in a container through an iterator
	vector<int>::iterator itBegin = v.begin();//Start the iterator, pointing to the location of the first element in the container
	vector<int>::iterator itEnd = v.end();//Ends the iterator, pointing to the next position of the last element in the container

	//The first traversal method
	while (itBegin != itEnd)
	{
		cout << *itBegin << endl;
		itBegin++;
	}

	cout << "****************************" << endl;
	//The second traversal method
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
	cout << "****************************" << endl;

	//The third traversal method uses the traversal algorithm in STL
	for_each(v.begin(), v.end(), myPrint);
}

int main()
{
	test01();
	return 0;
}

Exercise of storing custom data types in vector:

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

class Person
{
public:
	Person(string name, int age)
	{
		m_name = name;
		m_age = age;
	}

	string m_name;
	int m_age;
	
};

void test01()
{
	vector<Person> v;
	Person p1("aaa", 12);
	Person p2("bbb", 22);
	Person p3("ccc", 32);
	Person p4("ddd", 42);
	Person p5("eee", 52);

	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);
	v.push_back(p4);
	v.push_back(p5);

	for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << "name:" << (*it).m_name << " " << "age:" << (*it).m_age << endl;
		cout << "name:" << it->m_name << " " << "age:" << it->m_age << endl;
	}
}

void test02()
{
	vector<Person*> v;
	Person p1("aaa", 12);
	Person p2("bbb", 22);
	Person p3("ccc", 32);
	Person p4("ddd", 42);
	Person p5("eee", 52);

	v.push_back(&p1);
	v.push_back(&p2);
	v.push_back(&p3);
	v.push_back(&p4);
	v.push_back(&p5);

	for (vector<Person*>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << "name:" << (*it)->m_name << " " << "age:" << (*it)->m_age << endl;
	}
}

int main()
{
	test01();
	cout << "***************************" << endl;
	test02();
	return 0;
}

vector container nested container exercise Code:

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

//Container nested container
void test01()
{
	vector<vector<int>> v;
	//Create a small container
	vector<int> v1;
	vector<int> v2;
	vector<int> v3;
	vector<int> v4;

	//Adding data to a small container
	for (int i = 0; i < 4; i++)
	{
		v1.push_back(i + 1);
		v2.push_back(i + 2);
		v3.push_back(i + 3);
		v4.push_back(i + 4);
	}

	//Insert the small container into the large container
	v.push_back(v1);
	v.push_back(v2);
	v.push_back(v3);
	v.push_back(v4);

	//Traverse all data through a large container
	for (vector<vector<int>>::iterator it = v.begin(); it != v.end(); it++)
	{
		for (vector<int>::iterator vit = (*it).begin(); vit != (*it).end(); vit++)
		{
			cout << *vit << " " << endl;
		}
		cout << endl;
	}
}

int main()
{
	test01();
	return 0;
}

Exercises such as data access, insertion and deletion of vector container:

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

void printVector(vector<int>& v)
{
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

void test01()
{
	vector<int> v1;//Default construction (parameterless construction)
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	printVector(v1);


	//It is constructed by interval
	vector<int> v2(v1.begin(), v1.end());
	printVector(v2);

	//n elem ents
	vector<int> v3(10, 100);//10 100
	printVector(v3);

	//copy construction 
	vector<int> v4(v3);
	printVector(v4);
}

//vector assignment operation exercise
void test02()
{
	vector<int> v1;

	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}

	printVector(v1);

	//operator=
	vector<int> v2;
	v2 = v1;
	printVector(v2);

	//assign
	vector<int> v3;
	v3.assign(v1.begin(), v1.end());//Left closed right open section
	printVector(v3);

	//n element assignment
	vector<int> v4;
	v4.assign(10, 100);
	printVector(v4);
}

//vector container capacity and size exercise
void test03()
{
	vector<int> v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}

	printVector(v1);
	if (v1.empty())//True means the container is empty
	{
		cout << "v1 is null" << endl;
	}
	else
	{
		cout << "v1 is not null" << endl;
		cout << "v1 The capacity of the is:" << v1.capacity() << endl;
		cout << "v1 The size of the is:" << v1.size() << endl;
	}

	//Reassign size
	//If the re specified size is longer than the original space, it is filled with 0 by default
	v1.resize(15);
	//v1.resize(15, 100);// With overloaded versions, you can specify the default fill value
	printVector(v1);


	//If the re specified size is smaller than the original space, the excess data will be deleted
	v1.resize(5);
	printVector(v1);
}

//vector insertion and deletion exercises
void test04()
{
	vector<int> v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i + 1);
	}

	printVector(v1);

	//Tail deletion
	v1.pop_back();
	printVector(v1);

	//The first parameter inserted is an iterator
	v1.insert(v1.begin(), 100);
	printVector(v1);
	v1.insert(v1.begin(), 2, 1000);
	printVector(v1);

	//Deleting the first parameter is also an iterator
	v1.erase(v1.begin());
	printVector(v1);

	v1.erase(v1.begin(), v1.end());//Delete data in the interval
	printVector(v1);

	//empty
	v1.clear();
	printVector(v1);
}

//vector data access exercise
void test05()
{
	vector<int> v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i + 1);
	}
	
	//Access with []
	for (int i = 0; i < v1.size(); i++)
	{
		cout << v1[i] << " ";
	}
	cout << endl;
	
	//at mode access
	for (int i = 0; i < v1.size(); i++)
	{
		cout << v1.at(i) << " ";
	}
	cout << endl;

	//Gets the first and last element
	cout << "First element:" << v1.front() << endl;
	cout << "Last element:" << v1.back() << endl;
}

//vector swap container exercise
void test06()
{
	vector<int> v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i + 1);
	}

	cout << "Print before exchange:" << endl;
	printVector(v1);

	vector<int> v2;
	for (int i = 10; i >= 1; i--)
	{
		v2.push_back(i);
	}
	printVector(v2);

	cout << "Print after exchange:" << endl;
	v1.swap(v2);
	printVector(v1);
	printVector(v2);

	//Practical use: using swap skillfully can shrink memory space "
	vector<int> v;
	for (int i = 0; i < 100000; i++)
	{
		v.push_back(i);
	}
	cout << "Capacity:" << v.capacity() << endl;
	cout << "size:" << v.size() << endl;

	v.resize(3);
	cout << "Capacity:" << v.capacity() << endl;
	cout << "size:" << v.size() << endl;

	//Shrink memory with swap
	vector<int>(v).swap(v);

	//Vector < int > (V) - > anonymous object
	//Anonymous object features: the system will immediately recycle the current line after it is executed

	cout << "Capacity:" << v.capacity() << endl;
	cout << "size:" << v.size() << endl;
}

//vector reserved space
void test07()
{
	vector<int> v;

	//Reserve space with reserve
	v.reserve(100000);

	int num = 0;//Count the number of times to open up space
	int* p = nullptr;

	for (int i = 0; i < 100000; i++)
	{
		v.push_back(i);

		if (p != &v[0])
		{
			p = &v[0];
			num++;
		}
	}
	cout << "num:" << num << endl;
}


int main()
{
	//test01();
	//test02();
	//test03();
	//test04();
	//test05();
	//test06();
	test07();
	return 0;
}

3,string

The difference between string and char *

  • char * is a pointer
  • String is a class. char * is encapsulated inside the class to manage this string.

Exercise Code:

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

//string constructor exercise
void test01()
{
	string s1;//Default construction

	const char* str = "hello world";
	string s2(str);
	cout << "s2:" << s2 << endl;

	string s3(s2);
	cout << "s3:" << s3 << endl;

	string s4(10, 'a');
	cout << "s4:" << s4 << endl;
}


//string assignment operation exercise
void test02()
{
	string str1;
	str1 = "hello world";
	cout << "str1 = " << str1 << endl;

	string str2;
	str2 = str1;
	cout << "str2 = " << str2 << endl;

	string str3;
	str3 = 'a';
	cout << "str3 = " << str3 << endl;

	string str4;
	str4.assign("hello C++");
	cout << "str4 = " << str4 << endl;

	string str5;
	str5.assign("hello C++", 5);
	cout << "str5 = " << str5 << endl;

	string str6;
	str6.assign(str5);
	cout << "str6 = " << str6 << endl;

	string str7;
	str7.assign(10, 'w');
	cout << "str7 = " << str7 << endl;
}

//String splicing exercise
void test03()
{
	string str1 = "wo";
	str1 += "ai wan youxi ";
	cout << "str1:" << str1 << endl;

	str1 += ':';
	cout << "str1 = " << str1 << endl;

	string str2 = "lol dnf";
	str1 += str2;
	cout << "str1 = " << str1 << endl;

	string str3 = "I ";
	str3.append("love ");
	cout << "str3 = " << str3 << endl;

	str3.append("game abcd", 4);
	cout << "str3 = " << str3 << endl;

	//str3.append(str2);
	str3.append(str2,0,3);//Intercept 3 characters from position 0
	cout << "str3 = " << str3 << endl;
}

//string search operation exercise
void test04()
{
	string str1 = "abcdefede";
	int pos = str1.find("de");
	if (pos == -1)
	{
		cout << "String not found" << endl;
	}
	else
	{
		cout << "String found" << endl;
		cout << "pos = " << pos << endl;
	}

	pos = str1.rfind("de");
	cout << "pos = " << pos << endl;

	//The difference between rfind() and find(): rfind is from right to left, and find is from left to right
}

//string replacement exercise
void test05()
{
	string str1 = "abcdefg";
	str1.replace(1, 3, "1111");//Replace three characters from position 1 with 1111
	cout << "str1 = " << str1 << endl;
}

//String string comparison exercise
void test06()
{
	string str1 = "hello";
	string str2 = "xello";
	if (str1.compare(str2) == 0)
	{
		cout << "str1==str2" << endl;
	}
	else if (str1.compare(str2) > 0)
	{
		cout << "str1>str2" << endl;
	}
	else
	{
		cout << "str1<str2" << endl;
	}

}

//string access exercise
void test07()
{
	string str = "hello";
	cout << "str = " << str << endl;

	//Single character access via []
	for (int i = 0; i < str.size(); i++)
	{
		cout << str[i] << " ";
	}
	cout << endl;

	//Single character access via at mode
	for (int i = 0; i < str.size(); i++)
	{
		cout << str.at(i) << " ";
	}
	cout << endl;

	//Modify single character
	str[0] = 'x';
	cout << "str = " << str << endl;

	str.at(1) = 'x';
	cout << "str = " << str << endl;
}

//Insertion and deletion of string
void test08()
{
	string str = "hello";
	//insert
	str.insert(1, "111");
	cout << "str = " << str << endl;

	//delete
	str.erase(1, 3);
	cout << "str = " << str << endl;
}

//string substring interception exercise
void test09()
{
	string str = "abcdef";
	string subStr = str.substr(1, 3);
	cout << "subStr = " << subStr << endl;

	string email = "zhangsan@sina.com";

	//Get the user name information from the email address
	int pos = email.find("@");
	string username = email.substr(0, pos);
	cout << "username = " << username << endl;
}

int main()
{
	/*test01();
	cout << "**************************" << endl;
	test02();
	cout << "**************************" << endl;
	test03();*/

	/*test04();
	test05();*/

	//test06();
	//test07();

	//test08();
	test09();
	return 0;
}

🤦‍♀️🤦‍♀️🤦‍♀️

Keywords: C++ data structure Container

Added by hofdiggity on Thu, 06 Jan 2022 15:02:39 +0200