STL——string (two)

Table of contents

string class iterator

iterate over the array

 reverse traversal

const iterator

[ ] Overload

at

back&&front 

 insert

erase

replace

string::swap

c_str

find 

rfind

 find_last_of

 operator overloading


 

Earlier we briefly introduced some commonly used member functions of string. Today we will selectively explain the string class. What is not commonly used does not mean that it is useless. We must know that the commonly used ones must be mastered.

string class iterator

2edcac4678d54ce9a77f6ca98c9b0055.png

iterate over the array

e42faa6ce0934cda9d8e8e2523f84a6f.png

34e940d92b28493287f74dd3c45b2210.png In addition to traversing the array with size(), here I briefly introduce the operation of using an iterator to access each element of the array, which also paves the way for our later learning.

string a("hello world");
	string::iterator it = a.begin();
	while (it != a.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

As an independent type, iterator needs to specify string:: to be parsed into an iterator inside string. The begin and end here are superficially understood as pointers, which probably look like the picture below.
a39c8b39b8254feb99a4ece4dc099dcc.png

  In addition to using this method, we can also use range for, and the bottom layer is an iterator.

e91af1d3c709426eb269651727b292b2.png

 reverse traversal

Reverse traversal is implemented by means of reverse iterators, here we use rbegin and rend.

090a0561f9ae4d2795062c31f8907985.png

 The traversal structure should look like this:

71f9cd074471467784ec6fceeb271cdd.png

const iterator

As the name implies, const iterators are used to return const objects. When we traverse the array, we can add const because it does not involve changing the object .

void Func(const string& s)
{
	string::const_iterator it = s.begin();//只能读不能写
	while (it != s.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

At this time, the name has changed. Note that the const here has an underscore, which is a name and not a keyword. The object that is actually modified by const is not it (the return value of begin)

const forward iterator declaration: 

const_iterator begin() const;//修饰this指针

 We can also understand it like this:

const int* p;//指向的对象不能改变

The same goes for reverse iterators.

If you find it troublesome, you can use auto to automatically deduce the type:
2b9409588dac49809877948360654e1a.png

The type deduced by auto here is the object return type, and here we define an object of const type. 

In order to distinguish const from ordinary iterators, the string class adds such functions:

648264bdb40a478380a0820b96f88a3a.png

 The usage is basically the same, and everyone can use it according to their own specifications.

5f7b3b16b25c4429a79efba8697374fc.png

[ ] Overload

89983ed1464d4bc98da784bf488453f1.png

Pay attention to the distinction between const and ordinary objects

The iterator does not seem to be convenient to use [ ] overload directly, but its appearance can solve some very complicated data structures in the future. I hope everyone has a clear understanding of this.

at

87d7659372c74f118cf0dbaa58474d31.png

 The difference from [] is the check for out-of-bounds, the former is assert, the latter is the way of throwing an exception, we can find the exception by catching it.

bad186f4fcb84fb48083472acea9b472.png

back&&front 

 back and front are the first and last elements of the returned string array (excluding \0)

25c80f79c99a4416b7d4a1ee51816329.png

 insert

0d668f14b206464e88bb72966308b790.png

 Let's simply write a few insert instances

c-string (3)	string& insert (size_t pos, const char* s);

It means to insert a string at position pos (array subscript)

742a3a6741ad45ee880a163682cb1cf7.png

string& insert (size_t pos, size_t n, char c);

 It means to insert n characters c at position pos

dc985db0b9404a4abfd685d4533933cc.png

iterator insert (iterator p, char c);

 Iterator insertion:c6bac77add3f4a358938755de856c7ff.png

 Under normal circumstances, we do not recommend using insert to insert data. Combined with the knowledge of data structure, we know that inserting needs to move space and increase the complexity. You can check the document when necessary.

erase

The opposite of insert is erase, which deletes elements.

8e4b87fe00a549a48a8feabc5e05642e.png

 Here we introduce the first two:

327105f8aedf4c73a4b2f95ae77284b3.png

 Iterator single parameter can delete an element at position pos. If the deletion length len is greater than the length of the array itself, all subsequent elements will be deleted. Likewise, erase is not recommended for frequent use.

replace

replace can replace characters or strings at specified positions, but there are two disadvantages of using replace. The first is that there is not enough space to expand the capacity, and the second is the need to move data. Let's take an example of filling the spaces in a string to see the common usage of replace.

Before that, we need to introduce find to find the position of the space:

size_t find (char c, size_t pos = 0) const;

To traverse string, we can use string::npos (static member) to loop: 

e9776c6ba94b4bc1bd442c51a9142b62.png

It means that if the match fails, -1 (the maximum value of the integer) will be returned 

The replace used:

string& replace (size_t pos,  size_t len,  const char* s);

It means to replace the last len ​​characters at position pos with a string. 

Here we use reserve to open up space in advance, avoiding the consumption of expansion, reallocation of space and copying content . Then we use a loop to traverse the string, because the filled content is no longer a space. In order to avoid useless searches, we skip the string directly , which improves the search efficiency. 

string s2("i  love you more than you will ever know");
	size_t num = 0;
	for (auto ch : s1)
	{
		if (ch == ' ')
		{
			num++;
		}
	}
	//提前开空间,避免扩容
	s2.reserve(s2.size() + 2 * num);
		size_t i = s2.find(' ');
	while (i != string::npos)
	{
		s2.replace(i, 1, "%20");
		i = s2.find(' ',i+3);
	}

 Output result:

d087b8722e3f45578c6fbd730a24cb0e.png

Although it has been carefully processed, the movement of data is still indispensable. Here we briefly introduce the method of exchanging space for time:

	string New_s2;
	New_s2.reserve(s2.size() + 2 * num);
	for (auto ch : s2)
	{
		if (ch != ' ')
		
			New_s2 += ch;
		else
			New_s2 += "%20";
	}
	s2 = New_s2;
	cout << New_s2 << endl;

string::swap

e3e89ee2fae54e4f8f635ddacdf5cb8f.png

Why write the string class field in front? That's because there is also a template-like swap function in std, but the usage is different, so what is the difference between them?

Efficiency comparison:

The swap exchange in string only needs to change the pointing of the pointer to realize the exchange of elements. The swap of class templates involves deep copying , and its implementation logic may be more complicated, which we will talk about later.

dab60ed0e39642fb9b6963b3d5d7a2e3.png

c_str

 99d7760dba7745fbb638390195e696d1.png

 The appearance of this interface is mainly to be compatible with the string returned in C style. What does it mean? Let us illustrate with an example.

b096f66096ab4b4abc3a3ca5244f52ae.png  It can be seen that there is no difference in the first printing. The second time s3 encounters \0 and does not terminate and continue to output the following content, but c_str ends the printing. In c language, \0 is used as the end mark of char* type , and c_str inherits this feature, records the value of string in the form of constant pointer, and directly uses the string overloaded with cout to output its entire size The size does not need to control whether \0 exists or not.

When we use the c interface to open the string type file name, in order to distinguish the c++ interface, we need to use this c interface.

31417470652141b09bb1af3a24c182f6.png

 successfully read content

find 

9f047b3b3bc4498a9a96e5c923e797e0.png

As you can see, find can find constant strings, string types and single characters.

Let's take finding the file suffix as an example to explain

Here we use the substr interface to save the suffix name

31eec80bbed9481bb5b3ebcae27d30da.png

 The usage is to keep the npos string after the pos position .

1434596fb4614c4483736889d6377b57.png

 Here you can directly use the default npos of substr to directly fetch . and then end the file name.

Think about what to do if there are multiple suffixes and want to take its real suffix (the last suffix)?

In addition to the find interface, string also provides the rfind interface, which means reverse lookup .

rfind

86e19e48d76b497d9043b7e8e702d967.png

 Using the function of npos to look forward from the last one , we can modify the code like this:

string file("test.cpp.zip");
	size_t pos = file.rfind('.');
	if (pos != string::npos)
	{
		string sf = file.substr(pos);
		cout << sf << endl;
	}

Here is a code to find the URL, you can understand it by yourself

string url("http://www.cplusplus.com/reference/string/string/find/");
		cout << url << endl;
		size_t start = url.find("://");
		if (start == string::npos)
		{
			cout << "invalid url" << endl;
		}
		else
		{
			start += 3;
			size_t end = url.find('/', start);
			string address = url.substr(start,end-start);
			cout << address << endl;
		}

find_fisrt_of 

72366001e42946b786a75722a774e781.png

Note that first here is easily misunderstood as looking for the first string, but actually it will look for any characters or strings  that appear . As long as any one of these characters is found , it will return.

ecf394869a854984bcf697b19d9a0984.png The first value of found = is the number of matching strings, where the initial value of found is 3.

 find_last_of

Contrary to find_first_of, find_last_of looks backwards. You can look at the official library to understand

f6340289cd3b4fc19a1e7c666cbcd48e.png

 In addition, there are the following two interfaces that have the opposite effect on them, let's find out.ed26a6505d354842992686e83d09856b.png

 operator overloading

In the section on operator overloading, we have simulated and implemented the operators of the date class. I believe everyone is familiar with it. It should be noted that the string class does not have - operator overloading, and there is + overloading , but use it as little as possible (involving copying).

I hope that everyone will have a deeper understanding of string through today's study, and I will write this part of the exercises as a blog and upload them. If you like it, don't forget to click and triple! 

 

Guess you like

Origin blog.csdn.net/dwededewde/article/details/130872641