C++ STL ---- string

目录

目录

一.STL简介

1.什么是STL

2.STL的版本

3.STL的六大组件

4.STL的重要性

5.如何学习STL

6.STL的缺陷

二.STL--string的使用与模拟实现

1.string的使用

1.1了解string

1.2string常用接口

 string类对象的容量操作

  string类对象的访问及遍历操作

 string类对象的修改操作

string类非成员函数

2.string的模拟实现



一.STL简介

1.什么是STL

STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。

2.STL的版本

原始版本

Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许任何人任意 运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一的条件就是也需要向原始版本一样做开源使 用。 HP 版本--所有STL实现版本的始祖。

P. J. 版本

由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用,不能公开或修改,缺陷:可读性比较低, 符号命名比较怪异。

RW版本

由Rouge Wage公司开发,继承自HP版本,被C+ + Builder 采用,不能公开或修改,可读性一般。

SGI版本

由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版 本。被GCC(Linux)采用,可移植性好, 可公开、修改甚至贩卖,从命名风格和编程 风格上看,阅读性非常高。我们后面学习STL要阅读部分源代码, 主要参考的就是这个版本。

此外,在C++STL学习过程中,博主推荐阅读侯捷老师的《STL源码剖析》,这本书参考的就是SGI版本的STL,一些网站上也有人上传了侯捷老师STL这块的视频,如果各位能点进我的这篇博客相信找到这些视频也不在话下(doge)

3.STL的六大组件

C++ STL ---- string_第1张图片

 几个名词可能有些陌生,但随着学习的深入自然会迎刃而解

4.STL的重要性

1.刷题,笔试中经常要用

无论是平时在各大平台刷题,还是将来找工作笔试都要涉及到STL,如vector,string,map,set等等等等

2.面试官的考核内容会涉及

很现实=-=

3.工作中

世界上有两种人,一种会STL的,一种不会STL的(bushi),会了这些STL显然能提高工作效率,当然对底层逻辑的了解时必不可少的

5.如何学习STL

C++ STL ---- string_第2张图片

 前辈的话语,字字珠玑

总之,学习STL三重境界就是:能用,明理,能扩展

(貌似学习任何东西都有类似的层级(小声))

6.STL的缺陷

1.STL库的更新太慢了。这个得严重吐槽,上一版靠谱是C++98,中间的C++03基本一些修订。C++11出 来已经相隔了13年,STL才进一步更新。

2. STL现在都没有支持线程安全。并发环境下需要我们自己加锁。且锁的粒度是比较大的。

3. STL极度的追求效率,导致内部比较复杂。比如类型萃取,迭代器萃取。

4. STL的使用会有代码膨胀的问题,比如使用vector/vector/vector这样会生成多份代码,当然这是模板语 法本身导致的。
 

emmmm以后有水平了再来想它的缺陷吧(bushi)

二.STL--string的使用与模拟实现

1.string的使用

1.1了解string

1. string是表示字符串的字符串类

2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。

3. string在底层实际是:basic_string模板类的别名,typedef basic_string string;

4. 不能操作多字节或者变长字符的序列。


在使用string类时,必须包含#include头文件以及using namespace std;

1.2string常用接口

我们可以在cplusplus等网站上查询常用stl容器的接口,发现眼花缭乱,其实我们常用的只有几个,在工作中用到的时候可以再查询,掌握了常用接口的使用以及实现,对于其他接口也能轻松掌握

标准库中string中有7个接口,下面讲解和使用其中4个

default(1)
string();
copy(2)
string (const string& str);
substring (3)
string (const string& str, size_t pos, size_t len = npos);
from c-string (4)
string (const char* s);
from sequence (5)
string (const char* s, size_t n);
fill (6)
string (size_t n, char c);
range (7)
template 
  string  (InputIterator first, InputIterator last);

string()

Constructs an empty string, with a length of zero characters

构造一个长度为0的空字符串

#include
#include
using namespace std;

int main()
{
string s;

cout << s;
return 0;
}

string(const char* s) 

Copies the null-terminated character sequence (C-string) pointed by s.

赋值s指向的以空字符结尾的C字符序列

C++ STL ---- string_第3张图片

string(size_t n, char c) 

Fills the string with n consecutive copies of character c

用字符c的n个连续副本填充字符串

C++ STL ---- string_第4张图片

string(const string&s)

Constructs a copy of str.

 拷贝构造

C++ STL ---- string_第5张图片

 string类对象的容量操作

size_t size() const;

Return length of string

返回字符串长度

Returns the length of the string, in terms of bytes.

This is the number of actual bytes that conform the contents of the string, which is not necessarily equal to its storage capacity.

这是构成字符串的实际字节数,这不一定等于容量

Note that string objects handle bytes without knowledge of the encoding that may eventually be used to encode the characters it contains. Therefore, the value returned may not correspond to the actual number of encoded characters in sequences of multi-byte or variable-length characters (such as UTF-8).

注意string对象处理字节时不知道可能用于编码对象的编码。因此返回值不一定等同于多字节或者可变长字符序列(如 UTF-8)

这里的更深层的理解就是:我们都是熟知ASCLL表,我们打印的字符,或者符号都是被数字所表示的。因为计算机是只认识二进制,所以这些字符或者符号都会变成二进制让计算机识别。世界上有各种语言,所以对应的就有不同的电脑编码。英文对应的电脑编码是ASCLL,中文对应的电脑编码很多时候就是统一码

统一码(Unicode),也叫万国码、单一码,由统一码联盟开发,是计算机科学领域里的一项业界标准,包括字符集、编码方案等。统一码是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。

统一码是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。统一码用数字0-0x10FFFF来映射这些字符,最多可以容纳1114112个字符,或者说有1114112个码位。码位就是可以分配给字符的数字。UTF-8、UTF-16、UTF-32都是将数字转换到程序数据的编码方案。分别映射为8位,16位,32位长的整数
C++ STL ---- string_第6张图片

size_t length() const;

Return length of string

返回字符串长度

length与size的实现相同,只是命名不一样,这个是历史遗留问题,就不用过多的吐槽,在后面容器中就再也没有length了,只在string中有。

C++ STL ---- string_第7张图片

size_t capacity() const;

Return size of allocated storage

返回分配容量的大小

C++ STL ---- string_第8张图片

bool empty() const;

Test if string is empty

空true 非空false

检验字符串是否为空

C++ STL ---- string_第9张图片

void clear();

Clear string

清空字符串

C++ STL ---- string_第10张图片

注意 

为了提高重复利用效率,只清空有效字符并不清理内存

reserve

void reserve (size_t n = 0);

Request a change in capacity

请求改变容量

vs2019环境下C++ STL ---- string_第11张图片

 vs2019下以1.5倍增容

C++ STL ---- string_第12张图片

 linux下2倍增容

void resize (size_t n);

void resize (size_t n, char c);

Resize string

调整字符串大小

C++ STL ---- string_第13张图片

  string类对象的访问及遍历操作

char& operator[] (size_t pos);

const char& operator[] (size_t pos) const;

Returns a reference to the character at position pos in the string.

返回pos位置的字符

C++ STL ---- string_第14张图片

iterator begin();

Returns an iterator pointing to the first character of the string

返回指向字符串第一个字符的迭代器 

const_iterator begin() const;

Returns an iterator pointing to the past-the-end character of the string.

返回一个指向字符串的结束字符的迭代器

C++ STL ---- string_第15张图片

 reverse_iterator rbegin();

Return reverse iterator to reverse beginning

返回以反向开始的反向迭代器
const_reverse_iterator rbegin() const;

Return reverse iterator to reverse end

返回反向端的反向迭代器

C++ STL ---- string_第16张图片

 string类对象的修改操作

void push_back (char c);

appends character c to the end of the string, increasing its length by one.

将字符c追加到字符串的末尾,将其长度增加1

C++ STL ---- string_第17张图片

string (1)
string& append (const string& str);
substring (2)
string& append (const string& str, size_t subpos, size_t sublen);
c-string (3)
string& append (const char* s);
buffer (4)
string& append (const char* s, size_t n);
fill (5)
string& append (size_t n, char c);
range (6)
template 
   string& append (InputIterator first, InputIterator last);

(1) string

Appends a copy of str.----追加str的副本

(2) substring

Appends a copy of a substring of str. The substring is the portion of str that begins at the character position subpos and spans sublen characters (or until the end of str, if either str is too short or if sublen is string::npos).

追加str的子字符串的副本。该子字符串是str的一部分,从字符位置子字符串开始,跨越子字符串字符(或直到str结尾,如果str太短或子字符串为string::npos)

(3) c-string

Appends a copy of the string formed by the null-terminated character sequence (C-string) pointed by s.

追加由s指向的以空结尾的字符序列(C字符串)形成的字符串的副本

(4) buffer

Appends a copy of the first n characters in the array of characters pointed by s.

追加由s指向的字符数组中前n个字符的副本

(5) fill

Appends n consecutive copies of character c.

追加n个字符c的连续副本。

(6) range

Appends a copy of the sequence of characters in the range [first,last), in the same order.

以相同的顺序追加范围[first,last]中字符序列的副本。
C++ STL ---- string_第18张图片

operator+=

Append to string

附加到字符串

string (1)
string& operator+= (const string& str);
c-string (2)
string& operator+= (const char* s);
character (3)
string& operator+= (char c);

C++ STL ---- string_第19张图片

 const char* c_str() const;

Get C string equivalent

获取等效的C字符串

C++ STL ---- string_第20张图片

find + npos 

static const size_t npos = -1;(四十多亿的一个数值)

string (1)
size_t find (const string& str, size_t pos = 0) const;
c-string (2)
size_t find (const char* s, size_t pos = 0) const;
buffer (3)
size_t find (const char* s, size_t pos, size_t n) const;
character (4)
size_t find (char c, size_t pos = 0) const;

C++ STL ---- string_第21张图片

 rfind  

string (1)
size_t rfind (const string& str, size_t pos = npos) const;
c-string (2)
size_t rfind (const char* s, size_t pos = npos) const;
buffer (3)
ize_t rfind (const char* s, size_t pos, size_t n) const;
character (4)
size_t rfind (char c, size_t pos = npos) const;

C++ STL ---- string_第22张图片

string substr (size_t pos = 0, size_t len = npos) const;

(leetcod刷题的时候巨好用)

Returns a newly constructed string object with its value initialized to a copy of a substring of this object

返回一个新构造的字符串对象,其值初始化为此对象的子字符串的副本。
C++ STL ---- string_第23张图片

注意:

1. 在string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般 情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。

2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好


string类非成员函数

 
string (1)
string operator+ (const string& lhs, const string& rhs);
c-string (2)
string operator+ (const string& lhs, const char*   rhs);
string operator+ (const char*   lhs, const string& rhs);
character (3)
string operator+ (const string& lhs, char          rhs);
string operator+ (char          lhs, const string& rhs);

C++ STL ---- string_第24张图片

 ostream& operator<< (ostream& os, const string& str);

C++ STL ---- string_第25张图片

(1)
istream& getline (istream& is, string& str, char delim);
(2)
istream& getline (istream& is, string& str);

C++ STL ---- string_第26张图片

  relational operators (string)

(1) bool operator== (const string& lhs, const string& rhs);
bool operator== (const char*   lhs, const string& rhs);
bool operator== (const string& lhs, const char*   rhs);
 
(2) bool operator!= (const string& lhs, const string& rhs);
bool operator!= (const char*   lhs, const string& rhs);
bool operator!= (const string& lhs, const char*   rhs);
 
(3) bool operator<  (const string& lhs, const string& rhs);
bool operator<  (const char*   lhs, const string& rhs);
bool operator<  (const string& lhs, const char*   rhs);
 
(4) bool operator<= (const string& lhs, const string& rhs);
bool operator<= (const char*   lhs, const string& rhs);
bool operator<= (const string& lhs, const char*   rhs);
 
(5) bool operator>  (const string& lhs, const string& rhs);
bool operator>  (const char*   lhs, const string& rhs);
bool operator>  (const string& lhs, const char*   rhs);
 
(6) bool operator>= (const string& lhs, const string& rhs);
bool operator>= (const char*   lhs, const string& rhs);
bool operator>= (const string& lhs, const char*   rhs);
 

C++ STL ---- string_第27张图片

2.string的模拟实现

class string
	{
	public:
		typedef char* iterator;
		typedef const char* const_iterator;
		friend istream& operator>>(istream& in, const string& s);
		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}
		void push_back(char ch)
		{
			if (_size == _capacity)
			{
				size_t newcapacity = _capacity == 0 ? 2 : _capacity * 2;
				/*
				char* newstr = new char[newcapacity + 1];
				strcpy(newstr , _str);
				delete[] _str;
				_str = newstr;
				_capacity = newcapacity;
				*/
				reserve(newcapacity + 1);
			}
			_str[_size++] = ch;
			_str[_size] = '\0';
		}
		void append(const char* str)
		{
			size_t len = strlen(str);
			if (_size + len > _capacity)
			{
				size_t newcapacity = _size + len;
				/*
				char* newstr = new char[newcapacity + 1];
				strcpy(newstr , _str);
				delete[] _str;
				_str = newstr;
				_capacity = newcapacity;
				*/
				reserve(newcapacity + 1);
			}
			strcpy(_str + _size, str);
			_size += len;
		}
		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* newstr = new char[n];
				strcpy(newstr, _str);
				delete[] _str;
				_str = newstr;
				_capacity = n;
			}
		}
		void resize(size_t n, char ch = '\0')
		{
			if (n >= _size)
			{
				if (n > _capacity)
				{
					reserve(n);
				}
				for (size_t idx = _size; idx < n; ++idx)
				{
					_str[idx] = ch;
				}
			}
			_str[_size = n] = '\0';
		}
		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}
		string& operator+=(const char* str)
		{
			append(str);
			return *this;
		}
		string(const char* str = "")
		{
			_size = strlen(str);
			_capacity = _size;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}
		string(const string& s) :_str(new char[s._capacity]), _size(s._size), _capacity(s._capacity)
		{
			strcpy(_str, s._str);
		}
		char& operator[](const size_t idx)
		{
			assert(idx < _size);
			return _str[idx];
		}
		const char& operator[](const size_t idx)const
		{
			assert(idx < _size);
			return  _str[idx];
		}
		bool operator ==(const string& s)
		{
			return strcmp(_str, s._str) == 0;
		}
		bool operator <(const string& s)
		{
			return strcmp(_str, s._str) < 0;
		}
		bool operator >(const string& s)
		{
			return !(*this <= s);
		}
		bool operator <=(const string& s)
		{
			return *this == s || *this < s;
		}
		bool operator >=(const string& s)
		{
			return !(*this < s);
		}
		bool operator !=(const string& s)
		{
			return !(*this == s);
		}
		string& operator=(const string& s)
		{
			if (this != &s)
			{
				char* tmp = new char[s.capacity()];
				strcpy(tmp, s._str);
				delete[] _str;
				_str = tmp;
				_size = s._size;
				_capacity = s._capacity;
			}
			return *this;
		}
		size_t size()const
		{
			return _size;
		}
		size_t capacity()const
		{
			return _capacity;
		}
		const char* c_str()const
		{
			return _str;
		}
		~string()
		{
			delete[] _str;
			
		
			_size = _capacity = 0;
			_str = nullptr;
		}
		string& insert(size_t pos, char ch)
		{
			assert(pos < _size);
			if (_size == _capacity)
			{
				size_t newcapacity = _capacity == 0 ? 2 : _capacity * 2;
				reserve(newcapacity + 1);
			}
			size_t end = _size;
			while (end > pos)
			{
				_str[end] = _str[end - 1];
				end--;
			}
			_str[end] = ch;
			++_size;
			_str[_size] = '\0';
			return *this;
		}
		string& insert(size_t pos, const char* str)
		{
			assert(pos < _size);
			size_t len = strlen(str);
			if (_size + len >= _capacity)
			{
				size_t newcapacity = _size + len;
				reserve(newcapacity + 1);
			}
			size_t end = _size - 1 + len;
			while (end - len > pos)
			{
				_str[end] = _str[end - len];
				end--;
			}
			_str[end] = _str[end - len];
			strncpy(_str + pos, str, len);
			_size += len;
			return *this;
		}
		void erase(size_t pos, size_t len = npos)
		{
			assert(pos < _size);
			if (len > _size - pos)
			{
				_str[pos] = '\0';
				_size = pos;
			}
			else
			{
				size_t idx = pos;
				while (idx + len < _size)
				{
					_str[idx] = _str[idx + len];
					idx++;
				}
				_str[idx] = '\0';
				_size -= len;
			}
		}
		size_t find(const char* str, size_t pos = 0)
		{
			char* p = strstr(_str, str);
			if (p)
			{
				return p - _str;
			}
			return npos;
		}
		void clear()
		{
			_str[_size = 0] = '\0';
		}
		bool empty()
		{
			return _size == 0;
		}
	private:
		char* _str;
		size_t _size;
		size_t _capacity;
		static size_t npos;
	}
	;
	size_t string::npos = -1;
	ostream& operator<<(ostream& out, const string& s)
	{
		for (size_t i = 0; i < s.size();
			++i)
			out << s[i];
		return out;
	}
	istream& operator>>(istream& in, const string& s)
	{
		in >> s._str;
		return in;
	}

你可能感兴趣的:(c++,开发语言,microsoft)