当前位置: 首页 > news >正文

09 string的实现

注意

实现仿cplus官网的的string类,对部分主要功能实现

实现

头文件

#pragma once
#include <iostream>
#include <assert.h>
#include <string>namespace mystring
{class string{friend std::ostream& operator<<(std::ostream& os, const string& str);public://迭代器typedef char* iterator;typedef const char* cosnt_iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}cosnt_iterator begin() const{return _str;}cosnt_iterator end() const{return _str + _size;}//初始化string(const char* str = "");string(const string& obj);string& operator=(const string& obj);//增void PsuhBack(char ch);string& Append(const char* str);string& Insert(size_t pos, char ch);string& Insert(size_t pos, const char* str);string& operator+=(char ch);string& operator+=(const char* str);void Reserve(size_t capacity);void Resize(size_t capacity, char ch = '\0');//删string& Erase(size_t pos, size_t n = npos);void Clear();//查size_t Find(char ch, size_t pos = 0);size_t Find(char* str, size_t pos = 0);const char* c_str() const{return _str;}size_t size() const{return _size;}size_t capacity() const{return _capacity;}//改char& operator[](size_t pos){assert(pos < _size);return _str[pos];}const char& operator[](size_t pos) const{assert(pos < _size);return _str[pos];}void Swap(string& obj);//不修改成员变量的,最好const//比较bool operator>(const string& s) const{return strcmp(_str, s._str) > 0;}bool operator==(const string& s) const{return strcmp(_str, s._str) == 0;}bool operator<(const string& s) const{return strcmp(_str, s._str) < 0;}bool operator>=(const string& s) const{return *this > s || s == *this;}bool operator<=(const string& s) const{return *this < s || *this == s;}bool operator!=(const string& s) const{return !(*this == s);}//析构~string(){delete[] _str;_str = nullptr;_size = _capacity = 0;}private:char* _str;size_t _size;size_t _capacity;static size_t npos;};std::ostream& operator<<(std::ostream& os, const string& str);std::istream& operator>>(std::istream& is, string& str);}

实现

#define _CRT_SECURE_NO_WARNINGS 1
#include "String.h"using namespace mystring;size_t string::npos = -1;mystring::string::string(const char* str):_size(strlen(str))
{_capacity = _size == 0 ? 3 : _size + 1;_str = new char[_capacity];strcpy(_str, str);
}mystring::string::string(const string& obj):_size(obj._size),_capacity(obj._capacity)
{_str = new char[_capacity];strcpy(_str, obj._str);
}void string::PsuhBack(char ch)
{if (_size + 1>= _capacity){//扩容Reserve(_capacity * 2);}_str[_size] = ch;_size++;_str[_size] = '\0';//insert(_size, ch);
}string& mystring::string::Append(const char* str)
{size_t len = strlen(str);if (_size + len >= _capacity){//扩容Reserve(_capacity + len);}strcpy(_str + _size, str);_size += len;return *this;
}string& mystring::string::Insert(size_t pos, char ch)
{assert(pos <= _size);if (_size + 1>= _capacity){//扩容Reserve(_capacity * 2);}int end = _size + 1;while (end > pos){_str[end] = _str[end - 1];end--;}_str[pos] = ch;_size++;return *this;
}string& mystring::string::Insert(size_t pos, const char* str)
{assert(pos <= _size);size_t len = strlen(str);if (_size + len >= _capacity){//扩容Reserve(_capacity + len);}size_t end = _size + len;while (end - len + 1> pos){_str[end] = _str[end - len];end--;}strncpy(_str + pos, str, len);_size += len;return *this;}string& mystring::string::operator+=(char ch)
{PsuhBack(ch);return *this;
}string& mystring::string::operator+=(const char* str)
{Append(str);return *this;
}void mystring::string::Reserve(size_t capacity)
{//比原空间小,不扩容,防止单独调用if (capacity > _capacity){char* tmp = new char[capacity];strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = capacity;}}void mystring::string::Resize(size_t capacity, char ch)
{//比元空间小,不缩容if (capacity > _capacity){Reserve(capacity + 1);memset(_str + _size, ch, capacity - _size);_size = capacity;_str[_size] = '\0';}else{_str[capacity] = '\0';_size = capacity;}
}string& mystring::string::Erase(size_t pos, size_t n)
{assert(pos < _size);//分三种情况,n全删和部分size_t end = pos;if (n == npos || pos + n >= _size){_str[pos] = '\0';//长度改为pos_size = pos;}else{/*while (end < _size - n){_str[end] = _str[end + n];end++;}_str[_size - n] = '\0';*/strcpy(_str + pos, _str + pos + n);_size -= n;}return *this;}void mystring::string::Clear()
{_size = 0;_str[_size] = '\0';
}size_t mystring::string::Find(char ch, size_t pos)
{assert(pos < _size);for (size_t i = pos; i < _size; i++){if (_str[i] == ch){return i;}}return npos;
}size_t mystring::string::Find(char* str, size_t pos)
{assert(pos < _size);char* p = strstr(_str + pos, str);if (p == nullptr){return npos;}else{return p - _str;}}void mystring::string::Swap(string& obj)
{std::swap(_str, obj._str);std::swap(_size, obj._size);std::swap(_capacity, obj._capacity);
}string& mystring::string::operator=(const string& obj)
{if (this != &obj){char* tmp = new char[obj._capacity];strcpy(tmp, obj._str);delete[] _str;_str = tmp;_size = obj._size;_capacity = obj._capacity;}return *this;
}std::ostream& mystring::operator<<(std::ostream& os, const string& str)
{for (auto ch : str){os << ch;}return os;
}std::istream& mystring::operator>>(std::istream& is, string& str)
{//cin遇到空格会退出str.Clear();char ch = is.get();//先存入临时数组,减少扩容次数char buff[128];size_t i = 0;while (ch != ' ' && ch != '\n'){buff[i++] = ch;if (i == 127){buff[127] = '\0';str += buff;i = 0;}ch = is.get();}//没有放入的if (i != 0){buff[i] = '\0';str += buff;}return is;/*str.Clear();char ch = is.get();char buff[128];size_t i = 0;while (ch != ' ' && ch != '\n'){buff[i++] = ch;if (i == 127){buff[127] = '\0';str += buff;i = 0;}ch = is.get();}if (i != 0){buff[i] = '\0';str += buff;}return is;*/}

测试

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
#include "String.h"
using namespace mystring;//void printstring(const string& s)
//{
//	string::cosnt_iterator it = s.begin();
//	while (it != s.end())
//	{
//		printf("%c", *it);
//		it++;
//	}
//}int main()
{string s1("abcd");std::string s2("abcd");//string s2("hello nih");//string::iterator it = s1.begin();/*for (size_t i = 0; i < s1.size(); i++){printf("%c",s1[i]);}*//*while (it != s1.end()){printf("%c", *it);it++;}*///s1 += 'a';//s1 += 'b';// += 'c';/*s1.Insert(0, 'y');s1.Insert(0, 'x');s1.Insert(2, "hello");*///s1.Insert(2, "hello");//s1.reserve();//s1.Erase(2,1);//s1.resize(10, 'x');//printf("%zd\n", s1.Find('b'));//printf("%zd\n", s2.find('b'));/*s2 += '\0';s2 += " www.nihao";s2.clear();*///s1 += '\0';//s1 += " www.he";std::cin >> s1;//std::cin >> s2;//string s2("world");//s2 = s1;//printf("size = %d\n capacity = %d\n%s\n", s1.size(), s1.capacity(), s1.c_str());//printf("s1 = s2 %d", s1 >= s2);//printstring(s1);std::cout << s1;return 0;
}

注意事项

容量默认比长度多一个,存储的\0
构造函数采用缺省构造,如果无参,默认为空字符串,如果为空指针,strlen计算长度会报错。因为容量依赖于长度,所以初始化列表先对size初始化。长度0时容量初始化为3,存储\0
插入功能注意0位置的插入,从size处开始会出错,因为size_t不会小于0的问题.所以选择从\0下一个位置开始挪
resize和reserve不会缩小容量,只会改变长度,resize判断两种情况,容量小于和大于目前的容量
erase如果长度是npos,就从pos位置全部删除,也需要分全删和部分删的情况
为了适应const对象调用下标,重载一个[]运算符,常成员函数返回常对象
swap比std的函数好的地方在于不需要构造,只需要交换三个成员变量
<<输出和c_str的区别,遇到\0c_str会停下来,<<按照长度打印
>>功能里cin遇到空格和换行会自动停下来,不会获取这个字符,导致while无限循环.所以改用io的get函数,空格和换行也会读取,用一个临时数组存够后一起放入对象里,避免多次扩容的浪费

vs的容量是默认15,如果超出则1.5倍扩容。而g++2倍扩容

写时拷贝

在浅拷贝的基础上增加了引用计数的方式
写时拷贝
写时拷贝的缺陷

扩展

测试时string的正确写法
STL的string类怎么了

相关文章:

09 string的实现

注意 实现仿cplus官网的的string类&#xff0c;对部分主要功能实现 实现 头文件 #pragma once #include <iostream> #include <assert.h> #include <string>namespace mystring {class string{friend std::ostream& operator<<(std::ostream&a…...

Git 进行版本控制时,配置 user.name 和 user.email

在使用 Git 进行版本控制时&#xff0c;配置 user.name 和 user.email 是一个非常重要的初始步骤&#xff0c;但不是绝对必须的。这两个配置项定义了当你进行提交&#xff08;commit&#xff09;时用于标识提交者的信息。 为什么建议配置 user.name 和 user.email 标识提交者…...

传统开发读写优化与HBase

目录: 一、传统开发数据读写性能优化 1. Mysql 分表、主从复制与读写分离 2. Redis(缓存型数据库)主从复制与读写分离 二、HBase 一、传统开发数据读写性能优化 1、Mysql 分表、主从复制与读写分离 mysql分库分表方案 一种分表方案&#xff1a;设置表A 表B 表A 自增列从1开始…...

【OpenGL实现 03】纹理贴图原理和实现

目录 一、说明二、纹理贴图原理2.1 纹理融合原理2.2 UV坐标原理 三、生成纹理对象3.1 需要在VAO上绑定纹理坐标3.2 纹理传递3.3 纹理buffer生成 四、代码实现&#xff1a;五、着色器4.1 片段4.2 顶点 五、后记 一、说明 本篇叙述在画出图元的时候&#xff0c;如何贴图纹理图片…...

FDU 2021 | 二叉树关键节点的个数

文章目录 1. 题目描述2. 我的尝试 1. 题目描述 给定一颗二叉树&#xff0c;树的每个节点的值为一个正整数。如果从根节点到节点 N 的路径上不存在比节点 N 的值大的节点&#xff0c;那么节点 N 被认为是树上的关键节点。求树上所有的关键节点的个数。请写出程序&#xff0c;并…...

精读《React Conf 2019 - Day2》

1 引言 这是继 精读《React Conf 2019 - Day1》 之后的第二篇&#xff0c;补充了 React Conf 2019 第二天的内容。 2 概述 & 精读 第二天的内容更为精彩&#xff0c;笔者会重点介绍比较干货的部分。 Fast refresh Fast refresh 是更好的 react-hot-loader 替代方案&am…...

向ChatGPT高效提问模板

PS: ChatGPT无限次数&#xff0c;无需魔法&#xff0c;登录即可使用,网页打开下面 tj4.mnsfdx.net [点击跳转链接](http://tj4.mnsfdx.net/) 我想请你XXXX&#xff0c;请问我应该如何向你提问才能得到最满意的答案&#xff0c;请提供全面、详细的建议&#xff0c;针对每一个建…...

android metaRTC编译

参考文章&#xff1a; metaRTC3.0稳定版本编译指南_metartc 编译-CSDN博客 源码下载&#xff1a; Releases metartc/metaRTC GitHub 版本v6.0-b4即可...

HDFS面试重点

文章目录 1. HDFS的架构2. HDFS的读写流程3.HDFS中&#xff0c;文件为什么以block块的方式存储&#xff1f; 1. HDFS的架构 HDFS的架构可以分为以下几个主要组件&#xff1a; NameNode&#xff08;名称节点&#xff09;&#xff1a; NameNode是HDFS的关键组件之一&#xff0c;…...

Java中的IO流是什么?

Java中的IO流&#xff08;Input/Output Stream&#xff09;是Java编程语言中用于处理输入和输出操作的一种重要机制。在Java中&#xff0c;IO流被用来读取和写入数据&#xff0c;这些数据可以来自各种来源&#xff0c;如文件、网络连接、内存缓冲区等。Java的IO流提供了丰富的类…...

Spring boot 集成netty实现websocket通信

一、netty介绍 Netty 是一个基于NIO的客户、服务器端的编程框架&#xff0c;使用Netty 可以确保你快速和简单的开发出一个网络应用&#xff0c;例如实现了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程&#xff0c;例如&#xff1a;基于TCP和U…...

数码管的动态显示(二)

1.原理 这个十六进制是右边的dp为高位。 数码管的动态显示&#xff0c;在第一个计数周期显示个位&#xff0c;在第二个周期显示十位&#xff0c;在第三个周期显示百位由于人眼的视觉和数码管的特性&#xff0c;感觉就是显示了234&#xff0c;每个数码管的显示需要从输入的数据里…...

【JavaScript】数据类型转换 ① ( 隐式转换 和 显式转换 | 常用的 数据类型转换 | 转为 字符串类型 方法 )

文章目录 一、 JavaScript 数据类型转换1、数据类型转换2、隐式转换 和 显式转换3、常用的 数据类型转换4、转为 字符串类型 方法 一、 JavaScript 数据类型转换 1、数据类型转换 在 网页端 使用 HTML 表单 和 浏览器输入框 prompt 函数 , 接收的数据 是 字符串类型 变量 , 该…...

git学习(创建项目提交代码)

操作步骤如下 git init //初始化git remote add origin https://gitee.com/aydvvs.git //建立连接git remote -v //查看git add . //添加到暂存区git push 返送到暂存区git status // 查看提交代码git commit -m初次提交git push -u origin "master"//提交远程分支 …...

Day36:安全开发-JavaEE应用第三方组件Log4j日志FastJson序列化JNDI注入

目录 Java-项目管理-工具配置 Java-三方组件-Log4J&JNDI Java-三方组件-FastJson&反射 思维导图 Java知识点&#xff1a; 功能&#xff1a;数据库操作&#xff0c;文件操作&#xff0c;序列化数据&#xff0c;身份验证&#xff0c;框架开发&#xff0c;第三方库使用…...

HTML5+CSS3+JS小实例:全屏范围滑块

实例:全屏范围滑块 技术栈:HTML+CSS+JS 效果: 源码: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale…...

ctf杂项总结

1.文件无法打开 1.1.文件拓展名损坏/错误导致 方法&#xff1a; 1.使用kali当中的file命令查看&#xff0c;之后修改为正确的后缀即可 2.通过16进制编辑器打开查看文件头 3.文件头残缺/错误&#xff0c;可以先使用kail当中的file命令查看它的类型&#xff0c;之后再通过 16…...

openAI key 与ChatGPTPlus的关系,如何升级ChatGPTPLus

一、前言 先详细介绍一下Plus会员和Open API之间的区别&#xff1a; 实际上&#xff0c;这两者是相互独立的。举例来说&#xff0c;虽然您开通了Plus会员&#xff0c;并不意味着您就可以使用4.0版本的API。尽管这两个账户可以是同一个&#xff0c;但它们是完全独立的平台。 …...

KB5034441 0x80070643 reagentc.exe 无法更新引导配置数据

微软2024年1月的更新补丁正常更新会出现0x80070643错误&#xff0c;原因是正常安装系统默认的恢复分区留小了&#xff0c;通过压缩系统盘空间然后在diskgenius扩容恢复分区空间可以解决这个问题&#xff0c;但是笔者在进行上述操作时依旧出现了报错&#xff0c;按照网上的说法可…...

全网最最最详细“Jupyter command ‘jupyter-notebook‘ not found.“的解决方案

"Jupyter command jupyter-notebook not found."。这通常意味着 jupyter-notebook 命令在当前的虚拟环境中未安装或未正确安装&#xff0c;因此系统无法识别此命令。 原因分析 未安装 Jupyter Notebook: 可能你的虚拟环境中还没有安装 Jupyter Notebook。虽然 Jupyt…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

《信号与系统》第 6 章 信号与系统的时域和频域特性

目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...