string接口[小白理解篇]

news/2024/7/27 8:41:16/文章来源:https://blog.csdn.net/2301_78524918/article/details/136720886

作文目的

本文是为了加深对string底层函数的一点理解(请勿与底层源码混为一谈),下面从模拟与注意项出发。

一.string 功能化模拟

1.迭代器模拟

迭代器,为实现简单便理解故使用指针的方式(非说明迭代器使用该方法实现)。其中的begin、end都是为了给迭代器提供范围。迭代器也只认该俩函数(不可使用其他名称)。

typedef  char* iterator;typedef  const char* const_iterator;const_iterator begin()const {return _str;}const_iterator end()const {return _str + _size;}iterator begin(){return _str;}iterator end(){return _str + _size;}char& operator[](size_t pos)const{assert(pos<_size);return _str[pos]; }const char operator[](size_t pos)const{assert(pos<_size);return _str[pos];}

2.reserve模拟

该模拟块的实现在于空间的扩展,该处的空间扩展方案并不受限制 可自行选择。切记释放空间,防止空间浪费(好习惯)。

void reserve(size_t sub){if(sub>_capacity){char* ret=new char[sub+1];delete []_str;_str=ret;_capacity=sub;}}

3.resize模拟实现块

该模块的实现需要分清情况,他是要扩大有效值范围,还是缩小范围,如果扩大是否有填充值,最大空间是否能够容纳,如:在不定义填充值时补充缺省值 \0,即不改变数据也扩大了空间,也能在需要时不必重构函数接口。

void resize(size_t size,char ch='\0'){if(size<_size){_str[size]='\0';}else{//可省略判断if(size>_capacity){reserve(size);}for(int i =_size;i<size;i++){_str[i]=ch;    }_str[size]='\0';}_size=size;}

4.insert 模拟实现块

在insert接口,不仅仅要实现单字符的插入,还要可插入字符串的能力;同时不管_str中是否有值

都要追加值,但是如果指定插入点超出实际有效值长时,也必须处理。其次空间不足时也得先扩充空间,不然会出现错误访问。

 void insert(size_t pos, char ch) {assert(pos <= _size);if (_size == _capacity) {reserve(_capacity == 0 ? 4 : 2 * _capacity);}//腾出一块空间,将pos之后的数据后移size_t end = _size + 1;while (end > pos) {_str[end] = _str[end - 1];end--;}_str[pos] = ch;_size++;}void insert(size_t pos, const char* str) {assert(pos <= _size);int size = strlen(str);if (size + _size > _capacity) {reserve(size + _size);}int end = _size + size;//下标while (end > _size + size-1) {_str[end] = _str[end - size];end--;}//在pos位置开始拷贝插入size个strncpy(_str + pos, str,size);_size += size;}

5.erase模拟实现块

该接口主在优化,当len大于_size,则一定是全删,不必浪费时间去处理,只有有值得有效调动是 才前移数据。

void erase (size_t pos = 0, size_t len = npos)
{assert (pos <_size);if(len>=_size-pos){  _str[pos]='\0';}else{while (_size>pos+len){_str[pos]=_str[pos+len];pos++;}}_size-=pos
}

6.find模拟实现块

find查找函数,与平时写的查找函数没什么区别,无非就是别越界。

size_t find (char c, size_t pos = 0) const;
{assert(pos<_size);for(int i=pos;i<_size;i++){if(_s[i]==c){return i;}}return npos;
}
size_t find (const char* c, size_t pos = 0) const;
{assert(pos<_size);const char*p=strstr(_str+pos,c);if(p)return p-_str;elsereturn npos;
}

7.substr模拟实现块

截取函数,顾名思义就是截取指定长度中有的效数据,当指定截取范围远大于有效范围是就只截取有效范围内的数据。

string substr (size_t pos = 0, size_t len = npos) const
{assert(pos<_size);string st="";if(len>=_size-pos){for(int i=pos;i<_size;i++){st+=_str[i];      }    }else{for(int i=pos;i<pos+len;i++){st+=_str[i];      }       }return st;
}

8.输入流

第一个代码并非有错误,但是他不太胜任这份工作,他对接口的调用太过于频繁,产生极大且不必要的浪费,故代码二采用模拟缓冲区的办法减轻对接口的调用浪费。

ps: in.get()是输入流提供的一个接收缓冲区单字符的接口,弥补cin不能读储空字符与换行符的缺点

ps: clear每次插入数据,都是一个新值,故清空空间。

/*istream& operator>> (istream& is, string& str){str.clear();char ch;ch=is.get();while(ch!=' '&&ch!='\n'){ch=is.get();str+=ch;}
return str;
}
*/
istream& operator>> (istream& is, string& str){str.clear();int i=0;char ch;char buff[128]="";ch=is.get();while(ch!=' '&&ch!='\n'){buff[i]=ch;i++;if(i==127){buff[127]='\0';i=0;str+=buff;         }ch=is.get();}buff[i]='\0';str+=buff;return is;}istream& getlien(istream& is, string& str){str.clear();int i=0;char ch;char buff[128]="";ch=is.get();while(ch!='\n'){buff[i]=ch;i++;if(i==127){buff[127]='\0';i=0;str+=buff;         }ch=is.get();}buff[i]='\0';str+=buff;return is;}

9.拷贝函数

两种方法都是按同一个方向指向,仅方法实现不同。

// s2(s1)
/*string(const string& s)
{_str = new char[s._capacity + 1];strcpy(_str, s._str);_size = s._size;_capacity = s._capacity;
}*/// s1 = s3;
/*string& operator=(const string& s)
{char* tmp = new char[s._capacity + 1];strcpy(tmp, s._str);delete[] _str;_str = tmp;_size = s._size;_capacity = s._capacity;return *this;
}*/string(string &str){string tmp(str);swap(str);}string& operator+(string str){swap(str);return *this;
}

二.完整版

#pragma once
#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<assert.h>
using namespace std;
namespace bit {class string {public:typedef  char* iterator;typedef  const char* const_iterator;const_iterator begin()const {return _str;}const_iterator end()const {return _str + _size;}iterator begin() {return _str;}iterator end() {return _str + _size;}string(const char* str = " "):_size(strlen(str)){_str = new char[_size + 1];strcpy(_str, str);_capacity = _size;}string(const string &str){string tmp(str._str);swap(tmp);}string& operator=( string str){swap(str);return *this;}~string(){delete[] _str;_str= nullptr;_size = _capacity = 0;}size_t size()const {return _size;}const char* c_str()const {return _str;}size_t capacity() {return _capacity;}void clear() {_str[0] = '\0';_size = 0;}const char& operator[](size_t i)const {assert(i < _size);return _str[i];}char& operator[](size_t i) {assert(i < _size);return _str[i];}void reserve(size_t sub) {if (sub > _capacity) {char* ret = new char[sub + 1];strcpy(ret, _str);delete[] _str;_str = ret;_capacity = sub;}}void resize(size_t size, char ch = '\0') {if (size <= _size) {_str[size] = '\0';_size = size;}else {if (size > _capacity) {reserve(size);}for (int i = _size; i < size; i++){_str[i] = ch;}_str[size] = '\0';_size = size;}}void insert(size_t pos, char ch) {assert(pos <= _size);if (_size == _capacity) {reserve(_capacity == 0 ? 4 : 2 * _capacity);}size_t end = _size + 1;while (end > pos) {_str[end] = _str[end - 1];end--;}_str[pos] = ch;_size++;}void insert(size_t pos, const char* str) {assert(pos <= _size);int size = strlen(str);if (size + _size > _capacity) {reserve(size + _size);}int end = _size + size;while (end > pos+size-1) {_str[end] = _str[end - size];end--;}strncpy(_str + pos, str, size);_size += size;}void append(const char* str) {insert(_size, str);}void push_back(const char ch) {insert(_size, ch);}string& operator+= (const char* s) {append(s);return *this;}string& operator+= (const char s) {push_back(s);return *this;}void erase(size_t pos = 0, size_t len = npos) {assert(pos < _size);if (len >= _size) {_str[pos]= '\0';}else {while (_size > pos + len){_str[pos]=_str[pos + len];pos++;}_str[pos]= '\0';}_size -= pos;}void swap(string& str) {std::swap(_str, str._str);std::swap(_size, str._size);std::swap(_capacity, str._capacity);}size_t find(char c,size_t pos=0)const{assert(pos < _size);for (int i = pos; i < _size; i++) {if (_str[i]== c) {return i;}}return npos;}size_t find(const char* c, size_t pos = 0) const{assert(pos <= _size);const char* p = strstr(_str + pos, c);if (p)return p - _str;elsereturn npos;}string substr(size_t pos = 0, size_t len = npos) const{string st = " ";assert(pos <= _size);if (len >= _size- pos){for (size_t i = pos; i< _size;i++){st+=_str[i];}}else{for (size_t i = pos; i< pos + len;i++){st+=_str[i];}}return st;}static const int npos;private:char* _str = nullptr;size_t _size = 0;size_t _capacity = 0;};const int string::npos = -1;void swap(string& rhs, string& lhs) {rhs.swap(lhs);}bool operator==(const string& rhs, const string& lhs) {return !strcmp(rhs.c_str(), lhs.c_str());}bool operator!=(const string& rhs, const string& lhs) {return !(rhs == lhs);}bool operator>(const string& rhs, const string& lhs) {return strcmp(rhs.c_str(), lhs.c_str());}bool operator>=(const string& rhs, const string& lhs) {return rhs == lhs || rhs > lhs;}bool operator<(const string& rhs, const string& lhs) {return !(rhs >= lhs);}bool operator<=(const string& rhs, const string& lhs) {return (rhs == lhs) || (rhs < lhs);}ostream& operator<<(ostream& os, const string& str){for (auto ret :str){os << ret;}return os;}istream& operator>> (istream& is, string& str){str.clear();int i = 0; char ch;char buff[128] = "";ch = is.get();while (ch != ' ' && ch != '\n') {buff[i]=ch;i++;if (i == 127){buff[128]='\0';i = 0;str+=buff;}ch = is.get();}buff[i]= '\0';str+=buff;return is;}istream& getline(istream& is, string& str){str.clear();size_t i = 0; char ch;char buff[128] = "";ch = is.get();while (ch != '\n') {buff[i] = ch;i++;if (i == 127){buff[127] = '\0';str += buff;i = 0;}ch = is.get();}if (i > 0) {buff[i] = '\0';str += buff;}return is;}
}

 本文多在理解,感谢观看!

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

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

相关文章

Docker之部署前后端分离项目(以若依为案例实施必会!!!)

文章目录 一、搭建局域网二、需要安装redis三、安装MySQL四、部署后端服务4.1使用Dockerfile自定义镜像 一、搭建局域网 四个服务器去部署。 ①启动容器②制作镜像③搭建局域网④容器之间的相互通信 搭建net-ry局域网&#xff0c;用于部署若依项目 docker network create …

一文了解Cornerstone3D中窗宽窗位的3种设置场景及原理

&#x1f506; 引言 在使用Cornerstone3D渲染影像时&#xff0c;有一个常用功能“设置窗宽窗位&#xff08;windowWidth&windowLevel&#xff09;”&#xff0c;通过精确调整窗宽窗位&#xff0c;医生能够更清晰地区分各种组织&#xff0c;如区别软组织、骨骼、脑组织等。…

2024 年中国高校大数据挑战赛赛题 D:行业职业技术培训能力评价完整思路以及源代码分享

中国是制造业大国&#xff0c;产业门类齐全&#xff0c;每年需要培养大量的技能娴 熟的技术工人进入工厂。某行业在全国有多所不同类型&#xff08;如国家级、 省级等&#xff09;的职业技术培训学校&#xff0c;进行 5 种技能培训。学员入校时需要 进行统一的技能考核&#xf…

UnityShader常用算法笔记(颜色叠加混合、RGB-HSV-HSL的转换、重映射、UV序列帧动画采样等,持续更新中)

一.颜色叠加混合 1.Blend混合 // 正常&#xff0c;透明度混合 Normal Blend SrcAlpha OneMinusSrcAlpha //柔和叠加 Soft Additive Blend OneMinusDstColor One //正片叠底 相乘 Multiply Blend DstColor Zero //两倍叠加 相加 2x Multiply Blend DstColor SrcColor //变暗…

scrcpy远程投屏控制Android

下载 下载后解压压缩包scrcpy-win64-v2.4.zip scrcpy连接手机 1. 有线连接 - 手机开启开发者选项&#xff0c;并开启USB调试&#xff0c;连接电脑&#xff0c;华为手机示例解压scrcpy&#xff0c;在scrcpy目录下打开终端&#xff0c;&#xff08;或添加scrcpy路径为环境变…

后端八股笔记-----mysql

Mysql 聚合查询————可以用增加一个实例表解决 多表查询————可以优化sql语句进行查询 &#x1f446; 显示Using index condition的话 说明是有优化的空间 &#x1f446;唯一索引指的是类似主键这种数据内容唯一的属性 &#x1f446;图中的最后一个sql的索引…

手写简易操作系统(九)--实现打印函数

前情提要 前面我们已经进入内核程序了&#xff0c;中间穿插了一点特权级的知识&#xff0c;现在我们开始准备一个打印函数 很不幸&#xff0c;还有汇编程序 一、C调用规约 因为涉及到C与汇编的联合编程&#xff0c;我们这里简述一下调用规约&#xff0c;调用规约就是约定参…

Jsp在Javaweb中扮演什么角色?

1.什么是Jsp JSP&#xff08;Java Server Pages&#xff0c;Java 服务器页面&#xff09;是一种动态网页技术&#xff0c;它允许在 HTML 页面中嵌入 Java 代码&#xff0c;并由 Web 服务器在请求页面时动态生成 HTML 页面。JSP 通常用于创建动态 Web 内容&#xff0c;如交互式表…

解锁基于LLMS的咒语:通过上下文学习重新思考对齐

一、写作动机&#xff1a; 最近的一项研究&#xff0c;LIMA&#xff0c;表明仅使用1K个示例进行SFT也可以实现显著的对齐性能&#xff0c;这表明对齐微调的效果可能是“表面的”。&#xff08;知识和推理能力来源于预训练&#xff0c;而不是必须通过对齐微调获得的。&#xff…

钉钉群内自定义机器人发送消息功能实现

文章目录 钉钉群内自定义机器人发送消息功能实现1、设置webhook自定义机器人2、查看官方文档&#xff0c;使用open api3、编写业务代码4、发送成功结果如下 钉钉群内自定义机器人发送消息功能实现 1、设置webhook自定义机器人 设置关键词 添加完成后&#xff0c;获得改机器人的…

小迪安全34WEB 攻防-通用漏洞文件上传黑白盒审计逻辑中间件外部引用

#知识点&#xff1a; 1、白盒审计三要素 2、黑盒审计四要素 3、白黑测试流程思路 #详细点&#xff1a; 1、检测层面&#xff1a;前端&#xff0c;后端等 2、检测内容&#xff1a;文件头&#xff0c;完整性&#xff0c;二次渲染等 3、检测后缀&#xff1a;黑名单&…

高级语言讲义2011计专(仅高级语言部分)

1.某公司采用公用电话传递数据&#xff0c;数据是四位的整数&#xff0c;为了安全。在传递过程中数据是加密的。加密规则如下&#xff0c;每位数字加5,然后用和除以10的余数代替该数字&#xff0c;再将第一位和第四位交换&#xff0c;第二位和第三位交换&#xff0c;编一程序&a…

Buran勒索病毒通过Microsoft Excel Web查询文件进行传播

Buran勒索病毒首次出现在2019年5月&#xff0c;是一款新型的基于RaaS模式进行传播的新型勒索病毒&#xff0c;在一个著名的俄罗斯论坛中进行销售&#xff0c;与其他基于RaaS勒索病毒(如GandCrab)获得30%-40%的收入不同&#xff0c;Buran勒索病毒的作者仅占感染产生的25%的收入,…

力扣热题100_矩阵_73_矩阵置零

文章目录 题目链接解题思路解题代码 题目链接 73.矩阵置零 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&…

机器视觉学习(一)—— 认识OpenCV、安装OpenCV

目录 一、认识OpenCV 二、通过pip工具安装OpenCV 三、PyCharm安装OpenCV 一、认识OpenCV OpenCV&#xff08;Open Source Computer Vision Library&#xff0c;开源计算机视觉库&#xff09;是一个跨平台的计算机视觉库&#xff0c;最初由威尔斯理工学院的Gary Bradski于199…

Python轴承故障诊断 (15)基于CNN-Transformer的一维故障信号识别模型

目录 往期精彩内容&#xff1a; 前言 1 轴承数据加载与预处理 1.1 导入数据 1.2 数据预处理&#xff0c;制作数据集 3 基于Pytorch的CNN-Transfromer轴承故障诊断分类 3.1 定义CNN-Transfromer分类网络模型 3.2 设置参数&#xff0c;训练模型 3.3 模型评估 代码、数据…

【学一点RISC-V】RISC-V IMSIC

IMSIC RISC-V AIA 文档 第三章 Incoming MSI Controller (IMSIC) 传入 MSI 控制器&#xff08;IMSIC&#xff09;是一个可选的 RISC-V 硬件组件&#xff0c;与 hart 紧密相连&#xff0c;每个 hart 有一个 IMSIC。IMSIC 接收并记录 Hart 的传入消息信号中断 (MSI)&#xff0c;并…

北京保险服务中心携手镜舟科技,助推新能源车险市场规范化

2022 年&#xff0c;一辆新能源汽车在泥泞的小路上不慎拖底&#xff0c;动力电池底壳受损&#xff0c;电池电量低。车主向保险公司报案&#xff0c;希望能够得到赔偿。然而&#xff0c;在定损过程中&#xff0c;保司发现这辆车的电池故障并非由拖底事件引起&#xff0c;而是由于…

学生时期学习资源同步-JavaSE手写代码试题

原创作者&#xff1a;田超凡&#xff08;程序员田宝宝&#xff09; 版权所有&#xff0c;引用请注明原作者&#xff0c;严禁复制转载 1、输入姓名、年龄、成绩之后&#xff0c;打印个人信息 2、输入考试成绩&#xff0c;分别用if和switch实现以下效果&#xff1a; >90 打…

Day31-计算机基础1

Day31-计算机基础1 1. 网络基础介绍1.1 什么是网络&#xff1f;1.2 为什么要有网络&#xff1f;1.3 运维人员需要学习哪些网络知识&#xff1f;1.4 按作用范围对网络分类 2.网络设备知识2.1 网络传输介质及传输信号2.2 网卡设备2.3 中继器&#xff08;RP repeater&#xff09;2…