C++第十九弹---string模拟实现(下)

个人主页: 熬夜学编程的小林

💗系列专栏: 【C语言详解】 【数据结构详解】【C++详解】

目录

1、修改操作

2、迭代器操作

3、字符串操作 

4、非成员函数重载操作

总结


1、修改操作

1、string& operator+= (const char* s);

//尾部插入字符串s
2、string& operator+= (char c);

//尾部插入字符c
3、void push_back (char c);

//尾部插入字符c
4、string& append (const char* s);

//尾部插入(追加)字符串s
5、void insert(size_t pos, char ch);

//在pos位置插入字符c
6、void insert(size_t pos, const char* str);

//在pos位置插入字符串str
7、void erase(size_t pos, size_t len = npos);

//从pos位置删除n个字符
8、void swap(string& s);

//把字符串数据进行交换

void push_back(char c)
{// 扩容 容量为0则固定为4 其他则*2if (_size == _capacity){reserve(_capacity == 0 ? 4 : 2 * _capacity);}_str[_size] = c;//_size下标插入字符c++_size;//将大小+1_str[_size] = '\0';//字符串最后位置给标志结束的\0
}
void append(const char* s)
{//追加字符串首先得判断空间是否足够size_t len = strlen(s);if (len > _capacity - _size)//空间不够则扩容{reserve(_size + len);//大小为原大小+插入字符串长度}strcpy(_str + _size, s);//将要追加的数据拷贝到原数据尾_size += len;//更新字符串大小
}
string& operator+=(char c)
{push_back(c);//调用尾插字符函数return *this;
}
string& operator+=(const char* str)
{append(str);return *this;
}
void insert(size_t pos, char ch)
{assert(pos <= _size);//断言,小于字符串大小才能进行插入操作// 扩容if (_size == _capacity){reserve(_capacity == 0 ? 4 : 2 * _capacity);}// end=_size会有无符号与有符号比较问题,因为pos恒大于等于0,end回到-1// 无符号与有符号比较 会提升至无符号比较 即end = -1 还会大于possize_t end = _size + 1;while (end > pos)//end==pos则循环停止{_str[end] = _str[end - 1];//将前面的元素往后面一个位置移动--end;}_str[pos] = ch;//pos位置赋值字符ch++_size;//更新大小
}void insert(size_t pos, const char* str)
{assert(pos <= _size);//pos小于字符串大小才能进行插入操作size_t len = strlen(str);if (len > _capacity - _size)//容量不够则扩容{reserve(_size + len);}size_t end = _size + len;while (end > pos + len - 1){_str[end] = _str[end - len];//将原数据向后移动len位置--end;}strncpy(_str + pos, str, len);//不需要拷贝\0因此使用strncpy拷贝len长度到原串_size += len;//更新大小
}
void erase(size_t pos, size_t len = npos)
{assert(pos < _size);if (len == npos || len >= _size - pos)//长度为npos或者大于等于字符串大小-pos即删除整个字符串{_str[pos] = '\0';//直接在pos位置给\0即可_size = pos;//pos为\0下标,刚还为字符串大小}else//将pos+len位置后的数据拷贝到pos为止{strcpy(_str + pos, _str + pos + len);_size -= len;//更新长度}
}
void swap(string& s)//交换类的成员变量即可,
{std::swap(_str, s._str);//调用库函数的swap模板函数std::swap(_size, s._size);std::swap(_capacity, s._capacity);
}

2、迭代器操作

注意:暂时我们理解的迭代器实质为指针,但不完全是指针,此处就通过指针来模拟实现。

typedef char* iterator;//将迭代器定义成char*类型
typedef const char* const_iterator;将迭代器定义成const char*类型


1、const char* begin() const;

//获取指向首元素的const迭代器
2、const char* end() const;

//获取指向尾元素的const迭代器
3、char* begin();

//获取指向首元素的迭代器
4、char* end();

//获取指向尾元素的迭代器

typedef char* iterator;
typedef const char* const_iterator;const char* begin() const
{return (const char*)_str;//返回首元素地址,const修饰因此强转类型
}
const char* end() const
{return (const char*)_str + _size;//尾元素下一个位置地址,即\0位置地址
}
char* begin()
{return _str;
}
char* end()
{return _str + _size;
}

3、字符串操作 

1、const char* c_str() const;

//获取C字符串首元素地址

2、size_t find(char ch, size_t pos = 0) const;

//从pos位置(默认从0位置)找字符ch,找到则返回下标,否则返回npos
3、size_t find(const char* sub, size_t pos = 0) const;

//从字符串sub的pos位置找是否有匹配的字符串,找到则返回第一个元素下标,否则返回npos
4、string substr(size_t pos = 0, size_t len = npos);

//从pos位置截取len长度(默认截取整个字符串)的子串

const char* c_str() const
{return _str;//返回首地址
}
size_t find(char ch, size_t pos = 0) const
{assert(pos < _size);//小于字符串大小才能进行查找for (size_t i = 0; i < _size; i++)//遍历字符串{if (_str[i] == ch)return i;//找到字符则返回下标}return npos;
}
size_t find(const char* sub, size_t pos = 0) const
{assert(pos < _size);const char* p = strstr(sub + pos, _str);//从sub+pos位置找,调用C语言库的找子串函数,找到则返回该值的地址,否则返回NULLif (p)//不为空则返回下标,指针相减即为相差个数,即下标{return p - _str;}else//为空返回npos{return npos;}
}
string substr(size_t pos = 0, size_t len = npos)
{assert(pos < _size);string sub;if (len >= _size - pos)//长度大于_size-pos即将整个字符串截取,也包括len==npos{for (size_t i = pos; i < _size; i++){sub += _str[i];//追加给sub}}else//否则截取len长度{for (size_t i = pos; i < len + pos; i++){sub += _str[i];}}return sub;
}

4、非成员函数重载操作

1、void swap(string& s1, string& s2);

//将类s1数据与类s2数据交换
2、bool operator==(const string& s1, const string& s2);

//比较s1与s2是否相等
3、bool operator<(const string& s1, const string& s2);

//比较s1是否小于s2
4、ostream& operator<<(ostream& out, const string& s);

//流插入,即打印字符串s
5、istream& operator>>(istream& in, string& s);

//流提取,即将输入的内容给s
6、istream& getline(istream& in, string& s);

//获取一行信息,即将输入中回车之前的信息给s

void swap(string& s1, string& s2)
{s1.swap(s2);//调用类成员交换函数,跟库函数中交换函数重载,先调用类成员函数
}
bool operator==(const string& s1, const string& s2)
{int ret = strcmp(s1.c_str(), s2.c_str());//调用C语言比较字符串函数,等于0则相等return ret == 0;
}
bool operator<(const string& s1, const string& s2)
{int ret = strcmp(s1.c_str(), s2.c_str());return ret < 0;
}ostream& operator<<(ostream& out, const string& s)
{for (auto ch : s){out << ch;//用范围for变量类}return out;
}istream& operator>>(istream& in, string& s)
{s.clear();//清空串schar ch = in.get();//C++库中输入函数,读取一个字符给chchar buff[128];//先开辟一个128字节空间,减少频繁扩容size_t i = 0;while (ch != '\n' && ch != ' ')//流提取不识别空格回车{buff[i++] = ch;//将字符赋值给buff数组if (i == 127)//字符串满了则追加给串s{buff[127] = '\0';//末尾追加标志符\0s += buff;i = 0;//再重新赋值字符给buff数组}ch = in.get();}if (i > 0)//i>0则再追加数据给s{buff[i] = '\0';s += buff;}return in;
}
istream& getline(istream& in, string& s)
{s.clear();char ch = in.get();char buff[128];size_t i = 0;while (ch != '\n')//不识别回车,其他原理同流插入{buff[i++] = ch;if (i == 127){buff[127] = '\0';s += buff;i = 0;}ch = in.get();}if (i > 0){buff[i] = '\0';s += buff;}return in;
}

总结


本篇博客就结束啦,谢谢大家的观看,如果公主少年们有好的建议可以留言喔,谢谢大家啦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/331969.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue移动端登录页面

使用的是vant组件&#xff0c;引用和使用组件请去官网学习&#xff0c;链接↓vant组件官网 <div class"center"><!-- 背景图片 --><div class"background"><imgsrc"/assets/background.jpg"width"100%"heigh…

2024年5月大语言模型论文推荐:模型优化、缩放到推理、基准测试和增强性能

前一篇文章总结了关于计算机视觉方面的论文&#xff0c;这篇文章将要总结了2024年5月发表的一些最重要的大语言模型的论文。这些论文涵盖了塑造下一代语言模型的各种主题&#xff0c;从模型优化和缩放到推理、基准测试和增强性能。 大型语言模型(llm)发展迅速&#xff0c;跟上…

MySQL 8.4.0 LTS 变更解析:I_S 表、权限、关键字和客户端

↑ 关注“少安事务所”公众号&#xff0c;欢迎⭐收藏&#xff0c;不错过精彩内容~ MySQL 8.4.0 LTS 已经发布 &#xff0c;作为发版模型变更后的第一个长期支持版本&#xff0c;注定要承担未来生产环境的重任&#xff0c;那么这个版本都有哪些新特性、变更&#xff0c;接下来少…

Spark-RDD-常用算子(方法)详解

Spark概述 Spark-RDD概述 Spark RDD 提供了丰富的方法来对数据进行转换和操作。 对 RDD&#xff08;Resilient Distributed Dataset&#xff09;的操作可以分为两大类&#xff1a;转换算子&#xff08;Transformations&#xff09;和行动算子&#xff08;Actions&#xff09;…

在aspNetCore中 使用System.Text.Json的定制功能, 将定制化的json返回给前端

C# 默认大写, 而大部分的前端默认小写, 这时候可以如此配置: builder.Services.AddControllers().AddJsonOptions((opt) > {opt.JsonSerializerOptions.PropertyNamingPolicy System.Text.Json.JsonNamingPolicy.CamelCase;opt.JsonSerializerOptions.WriteIndented true…

lspci 显示当前设备的PCI总线信息

lspci 显示当前设备的PCI总线信息 lspci 显示当前设备的PCI总线信息显示当前主机的所有PCI总线信息&#xff1a;以数字方式显示PCI厂商和设备代码同时显示数字方式还有设备代码信息以树状结构显示PCI设备的层次关系&#xff1a;更多信息 lspci 显示当前设备的PCI总线信息 lspc…

Python中别再用 ‘+‘ 拼接字符串了!

大家好&#xff0c;在 Python 编程中&#xff0c;我们常常需要对字符串进行拼接。你可能会自然地想到用 操作符将字符串连接起来&#xff0c;毕竟这看起来简单明了。 在 Python 中&#xff0c;字符串是不可变的数据类型&#xff0c;这意味着一旦字符串被创建&#xff0c;它就…

2024年【高压电工】新版试题及高压电工找解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 高压电工新版试题是安全生产模拟考试一点通生成的&#xff0c;高压电工证模拟考试题库是根据高压电工最新版教材汇编出高压电工仿真模拟考试。2024年【高压电工】新版试题及高压电工找解析 1、【单选题】 110KV及以下…

数据分析工程师——什么是数据分析?

数据分析工程师 对于目前就业市场上的技术岗位,除了开发、测试、运维等常见职位之外,数据类岗位也越来越成为热门的求职方向。本文将重点介绍 数据分析 这一新兴岗位。 看到「数据分析」这几个字,也许大家的第一印象一样,觉得要做的工作似乎并不难,有大量数据后根据业务…

人工智能万卡 GPU 集群的硬件和网络架构

万卡 GPU 集群互联&#xff1a;硬件配置和网络设计 一、背景 自从 OpenAI 推出 ChatGPT 以来&#xff0c;LLM 迅速成为焦点关注的对象&#xff0c;并取得快速发展。众多企业纷纷投入 LLM 预训练&#xff0c;希望跟上这一波浪潮。然而&#xff0c;要训练一个 100B 规模的 LLM&a…

Python 调整PDF文件的页面大小

在处理PDF文件时&#xff0c;我们可能会遇到这样的情况&#xff1a;原始PDF文档不符合我们的阅读习惯&#xff0c;或者需要适配不同显示设备等。这时&#xff0c;我们就需要及时调整PDF文档中的页面尺寸&#xff0c;以满足不同应用场景的需求。 利用Python语言的高效性和灵活性…

使用python对指定文件夹下的pdf文件进行合并

使用python对指定文件夹下的pdf文件进行合并 介绍效果代码 介绍 对指定文件夹下的所有pdf文件进行合并成一个pdf文件。 效果 要合并的pdf文件&#xff0c;共计16个1页的pdf文件。 合并成功的pdf文件&#xff1a;一个16页的pdf文件。 代码 import os from PyPDF2 import …

Arthas-快速使用

一、 arthas(阿尔萨斯)的基本介绍 开发人员可以尝试在测试环境或者预发环境中复现生产环境中的问题。但是&#xff0c;某些问题无法在不同的环境中轻松复现&#xff0c;甚至在重新启动后就消失了&#xff0c;如果您正在考虑在代码中添加一些日志以帮助解决问题&#xff0c;您将…

【STM32】计算定时器的溢出

TIM2、3、4、5、12、13、14在APB1上&#xff0c;最大计数频率84M。 TIM1、8、9、10、11在APB2上&#xff0c;最大计数频率168M。 time(arr1)/(prescale1)/Tclk 算出来的是秒 下图使用TIM14 84MHz 那么time33600*25000/8400000010S&#xff0c;10S进入一次中断 中断方式开…

Strategy设计模式

Strategy设计模式举例。 看图&#xff1a; 代码实现&#xff1a; #include <iostream>using namespace std;class FlyBehavior { public:virtual void fly() 0; };class QuackBehavior { public:virtual void quack() 0; };class FlyWithWings :public FlyBehavior …

kube-apiserver内存占用过多 go tool pprof 入门

目录 环境问题排查1、kube-apiserver %CPU 146 正常&#xff0c;%MEM 高达70&#xff0c;&#xff0c;load average 400&#xff0c;出现kswapd0进程。2、k describe node 看到 SystemOOM3、是否大量连接导致&#xff1f;4、通过prom查看指标5、访问K8s API6、pprof 火焰图 解决…

决策控制类软件项目的团队配置

决策控制类软件项目的团队配置怎样才是最合适的&#xff1f;目的就是实现高效的项目协作以及为企业降本增效。软件项目的主要费用来源是研发人员的开支以及差旅费用。 下面的思维导图从项目与产品的关系、团队架构、项目成员配置、项目可复制性、招聘这几点进行说明如何组织人…

Redis(1)-Jedis连接配置

问题 阿里云安装并启用Redis后&#xff0c;尝试在本地用Jedis调用&#xff0c;发现报错 public class Jedis01 {Testpublic void connect(){Jedis jedis new Jedis("101.37.31.211", 6379); // 公网ipjedis.auth("123"); // 密码String ping jedis.pin…