C++ : STL容器之string剖析

news/2024/10/7 17:59:36 标签: c++, 开发语言

在这里插入图片描述

STL容器之string剖析

  • 一、string 的迭代器
    • (一)起始迭代器
    • (二)末尾迭代器
    • (三)反向迭代器
  • 二、容量相关的函数
    • (一)size
    • (二)capacity
    • (三)resize
    • (四)reserve
    • (五)clear
    • (六)empty
  • 三、元素的访问和修改
    • (一)[ ]操作符重载和 at
    • (二)front 和 back
  • 三、元素的修改
    • (一)+= 运算符重载
    • (二)append
    • (三)push_back
    • (四)assign
    • (五)insert
    • (六)erase
    • (七)pop_back
  • 四、其它操作函数
    • (一)c_str
    • (二)substr
    • (三)find
  • 五、其他成员
    • (一)静态成员 npos
    • (二)全局函数 getline
    • 结束语

一、string 的迭代器

迭代器的原理:下面的实现中迭代器是由 typedef / using 关键字定义的类型

public:
	/*using iterator = char*;
	using const_iterator = const char*;*/

	typedef char* iterator;
	typedef const char* const_iterator;

(一)起始迭代器

返回第一个元素的迭代器
在这里插入图片描述

iterator begin()
{
	return _str;
}

const_iterator begin() const
{
	return _str;
}

(二)末尾迭代器

返回最后一个元素的下一个位置的迭代器

在这里插入图片描述

	iterator end()
	{
		return _str + _size;
	}

	const_iterator end() const
	{
		return _str + _size;
	}

(三)反向迭代器

和前面两个迭代器的实现原理相同,但是在遍历的时候要记得用++,而不是- -。
在这里插入图片描述
在这里插入图片描述


void test05() {
	string s1("hello, world");
	std::string::reverse_iterator it = s1.rbegin();
	while (it != s1.rend()) {
		cout << *it;
		it++;  //这里要用++
	}
}

在这里插入图片描述

二、容量相关的函数

(一)size

返回函数的元素数量,不包含’\0’.
在这里插入图片描述

size_t size() const
{
	return _size;
}

(二)capacity

返回 string 申请空间的大小
在这里插入图片描述

(三)resize

修改函数的元素大小。

使用规则:
如果 n 小于当前字符串长度,则当前值将缩短为其前 n 个字符,并删除第 n个字符以外的字符
如果 n 大于当前字符串长度,则通过在末尾插入所需数量的字符来扩展当前内容,以达到 n 的大小。如果指定了 c,则新元素将初始化为 c 的副本,否则,它们是值初始化字符(空字符)。

在这里插入图片描述

(四)reserve

请求根据计划的大小更改调整字符串容量,使得容量至少为 n 个字符
如果 n 大于当前字符串容量,则该容器将其容量增加到 n 个字符(或更大)除此之外,不做其他的改变。
此函数对字符串长度没有影响,也无法更改其内容。

在这里插入图片描述
在这里插入图片描述

(五)clear

清空字符串,使得元素数量改成0, 其它不改变。
在这里插入图片描述

void clear()
{
	_str[0] = '\0';
	_size = 0;
}

(六)empty

判断容器是否为空。
在这里插入图片描述

在这里插入图片描述

三、元素的访问和修改

(一)[ ]操作符重载和 at

重载[ ]操作符可以使得我们可以像数组一样的访问容器中的元素。重载有两个版本,const 对象使用const 版本,只读不可修改,普通版本可以读取和修改。
at 和[ ]几乎一致,只是写法上有略微差距。
在这里插入图片描述
在这里插入图片描述

		char& operator[](size_t i)
		{
			assert(i >= 0 && i < _size);
			return _str[i];
		}

		const char& operator[](size_t i) const
		{
			assert(i >= 0 && i < _size);
			return _str[i];
		}

在这里插入图片描述

(二)front 和 back

分别返回起始元素和末尾元素,和[ ] 一样,分别都有两个版本。
在这里插入图片描述
在这里插入图片描述

三、元素的修改

(一)+= 运算符重载

+= 是很好用的一个追加字符 / 字符串的运算符。
在这里插入图片描述

(二)append

在字符串末尾追加字符 / 字符串,版本有很多。
在这里插入图片描述

(三)push_back

在末尾追加字符,其实和前面两者区别不大,为了达到容器的一致性而添加的字符。
在这里插入图片描述

(四)assign

相当于构造函数,构造方式更多样化,下面的接口都有很多一致性。和追加的这套体系很像。
在这里插入图片描述

#include <iostream>
#include <string>

int main ()
{
  std::string str;
  std::string base="The quick brown fox jumps over a lazy dog.";

  // used in the same order as described above:

  str.assign(base);
  std::cout << str << '\n';

  str.assign(base,10,9);
  std::cout << str << '\n';         // "brown fox"

  str.assign("pangrams are cool",7);
  std::cout << str << '\n';         // "pangram"

  str.assign("c-string");
  std::cout << str << '\n';         // "c-string"

  str.assign(10,'*');
  std::cout << str << '\n';         // "**********"

  str.assign<int>(10,0x2D);
  std::cout << str << '\n';         // "----------"

  str.assign(base.begin()+16,base.end()-12);
  std::cout << str << '\n';         // "fox jumps over"

  return 0;
}

(五)insert

insert 函数的用法和之前都有一致性,只是多加了两个迭代器版本和插入元素的位置,因为涉及到数据的挪动,因此时间复杂度比较高,在项目中不建议使用。
在这里插入图片描述

#include <iostream>
#include <string>

int main ()
{
  std::string str="to be question";
  std::string str2="the ";
  std::string str3="or not to be";
  std::string::iterator it;

  // used in the same order as described above:
  str.insert(6,str2);                 // to be (the )question
  str.insert(6,str3,3,4);             // to be (not )the question
  str.insert(10,"that is cool",8);    // to be not (that is )the question
  str.insert(10,"to be ");            // to be not (to be )that is the question
  str.insert(15,1,':');               // to be not to be(:) that is the question
  it = str.insert(str.begin()+5,','); // to be(,) not to be: that is the question
  str.insert (str.end(),3,'.');       // to be, not to be: that is the question(...)
  str.insert (it+2,str3.begin(),str3.begin()+3); // (or )

  std::cout << str << '\n';
  return 0;
}

(六)erase

和 insert类似,由于牵涉到数据的挪动,因此并不推荐使用。
在这里插入图片描述

(七)pop_back

用来弹出最后一个字符
在这里插入图片描述

四、其它操作函数

(一)c_str

这个函数用来得到 string 里面的字符串,由于返回的是const 类型,因此要使用的话需要拷贝一份
在这里插入图片描述
实现原理

	const char* c_str() const
	{
		return _str;
	}

使用样例

#include <iostream>
#include <cstring>
#include <string>

int main ()
{
  std::string str ("Please split this sentence into tokens");

  char * cstr = new char [str.length()+1];
  std::strcpy (cstr, str.c_str());

  // cstr now contains a c-string copy of str

  char * p = std::strtok (cstr," ");
  while (p!=0)
  {
    std::cout << p << '\n';
    p = std::strtok(NULL," ");
  }

  delete[] cstr;
  return 0;
}

(二)substr

用来获取 string 容器的字串,返回一份拷贝。
在这里插入图片描述
实现原理

string string::substr(size_t pos, size_t len)
{
	assert(pos >= 0 && pos < _size);
	if (len > _size - pos) {
		len = _size - pos;
	}
	WGM::string s;
	s.reserve(len);
	for (int i = 0; i < len;i++)
	{
		s._str[i] = _str[pos++];
	}
	return s;
}

(三)find

查找指定的字符 / 字符串 / string串,默认从0位置开始查找。
一般和npos混合起来使用,来判断是否找到目标字符串。
在这里插入图片描述
使用样例

#include <iostream>       // std::cout
#include <string>         // std::string

int main()
{
	std::string str("There are two needles in this haystack with needles.");
	std::string str2("needle");

	// different member versions of find in the same order as above:
	std::size_t found = str.find(str2);
	if (found != std::string::npos)
		std::cout << "first 'needle' found at: " << found << '\n';

	found = str.find("needles are small grkwgeio", found + 1,  1);
	if (found != std::string::npos)
		std::cout << "second 'needle' found at: " << found << '\n';

	found = str.find("haystack");
	if (found != std::string::npos)
		std::cout << "'haystack' also found at: " << found << '\n';

	found = str.find('.');
	if (found != std::string::npos)
		std::cout << "Period found at: " << found << '\n';

	// let's replace the first needle:
	str.replace(str.find(str2), str2.length(), "preposition");
	std::cout << str << '\n';

	return 0;
}

五、其他成员

(一)静态成员 npos

用来表示整形的最大值
在这里插入图片描述

(二)全局函数 getline

从流中提取字符串到 str 中,直到遇到限定标识符 delim结束, 不写的化自动是\n.
在这里插入图片描述

结束语

许久未更,从头开始!接下来还会带来 Linux 的文章,小编会继续更新有用的内容!


http://www.niftyadmin.cn/n/5693153.html

相关文章

QT-多线程、线程池的使用

在进行桌面应用程序开发的时候&#xff0c; 假设应用程序在某些情况下需要处理比较复杂的逻辑&#xff0c;如果只有一个线程去处理&#xff0c;就会导致窗口卡顿&#xff0c;无法处理用户的相关操作。这种情况下就需要使用多线程&#xff0c;其中一个线程处理窗口事件&#xff…

单细胞组学大模型(6)--- LangCell,医学/细胞文本知识增强模型效果

–https://arxiv.org/abs/2405.06708 代码开源&#xff1a;https://github.com/PharMolix/OpenBioMed LangCell: Language-Cell Pre-training for Cell Identity Understanding 留意更多内容&#xff0c;欢迎关注微信公众号&#xff1a;组学之心 研究团队和研究单位 聂再清…

大数据新视界 --大数据大厂之 Alluxio 数据缓存系统在大数据中的应用与配置

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

服务无法启动

有个服务死活无法启动了&#xff0c;运行就直接退出&#xff0c;无任何日志。 调试程序&#xff0c;能进入main函数&#xff0c;能进入SpringApplication.run 说明底层无误。 各种折腾无果。 最终既然没有日志&#xff0c;应该是日志出了问题&#xff0c;问开发是否改配置&a…

Rust-枚举

Rust-枚举 本文介绍 Rust 枚举&#xff08;enumerations&#xff09;&#xff0c;也被称作 enums。 枚举允许你通过列举可能的 成员&#xff08;variants&#xff09; 来定义一个类型。 首先&#xff0c;我们会定义并使用一个枚举来展示它是如何连同数据一起编码信息的。接下…

基于深度学习的视频中的姿态跟踪

基于深度学习的视频姿态跟踪是一项用于从视频序列中持续检测和跟踪人体姿态的技术。它能够识别人体的2D或3D关键点&#xff0c;并在时间维度上进行跟踪&#xff0c;主要应用于人机交互、体育分析、动作识别和虚拟现实等领域。以下是视频姿态跟踪的主要原理和方法&#xff1a; …

开源跨平台三维模型轻量化软件osgGISPlugins-2、如何编译

上一篇&#xff1a;开源跨平台三维模型轻量化软件osgGISPlugins-1、简介 1、编译前的准备&#xff1a;安装、配置vcpkg包管理器 1&#xff09;安装及国内镜像替换教程(Windows和Linux环境都有):vcpkg国内镜像源替换 2&#xff09;下载第三方依赖库(Readme文档中所给出的百度网…

[C#]使用onnxruntime部署yolov11-onnx实例分割模型

【官方框架地址】 https://github.com/ultralytics/ultralytics.git 【算法介绍】 在C#中使用ONNX Runtime部署YOLOv11-ONNX实例分割模型&#xff0c;涉及到模型的加载、数据预处理、模型推理和后处理几个关键步骤。 首先&#xff0c;需要确保已经安装了ONNX Runtime的NuGe…