【数据结构】string(C++模拟实现)
string构造
string::string(const char* str):_size(strlen(str))
{_str = new char[_size + 1];_capacity = _size;strcpy(_str, str);
}// s2(s1)
string::string(const string& s)
{_str = new char[s._capacity + 1];strcpy(_str, s._str);_size = s._size;_capacity = s._capacity;
}// s1 = s3
// s1 = s1
string& string::operator=(const string& s)
{if (this != &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()
{delete[] _str;_str = nullptr;_size = _capacity = 0;
}
string容量操作
const char* string::c_str() const
{return _str;
}size_t string::size() const
{return _size;
}void string::reserve(size_t n)
{if (n > _capacity){char* tmp = new char[n + 1];strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = n;}
}
string类对象的访问和遍历操作
char& string::operator[](size_t pos)
{assert(pos < _size);return _str[pos];
}const char& string::operator[](size_t pos) const
{assert(pos < _size);return _str[pos];
}
const size_t string::npos = -1;string::iterator string::begin()
{return _str;
}string::iterator string::end()
{return _str + _size;
}string::const_iterator string::begin() const
{return _str;
}string::const_iterator string::end() const
{return _str + _size;
}size_t string::find(char ch, size_t pos)
{for (size_t i = pos; i < _size; i++){if (_str[i] == ch){return i;}}return npos;
}size_t string::find(const char* sub, size_t pos)
{char* p = strstr(_str + pos, sub);return p - _str;
}
string类对象的修改操作
void string::push_back(char ch)
{/*if (_size == _capacity){size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;reserve(newcapacity);}_str[_size] = ch;_str[_size + 1] = '\0';++_size;*/insert(_size, ch);
}// "hello" "xxxxxxxxxxxxx"
void string::append(const char* str)
{/*size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}strcpy(_str+_size, str);_size += len;*/insert(_size, str);
}string& string::operator+=(char ch)
{push_back(ch);return *this;
}string& string::operator+=(const char* str)
{append(str);return *this;
}void string::insert(size_t pos, char ch)
{assert(pos <= _size);if (_size == _capacity){size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;reserve(newcapacity);}/*int end = _size;while (end >= (int)pos){_str[end + 1] = _str[end];--end;}*/size_t end = _size + 1;while (end > pos){_str[end] = _str[end - 1];--end;}_str[pos] = ch;++_size;
}void string::insert(size_t pos, const char* str)
{assert(pos <= _size);size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}/*int end = _size;while (end >= (int)pos){_str[end + len] = _str[end];--end;}*/size_t end = _size + len;while (end > pos + len - 1){_str[end] = _str[end - len];--end;}memcpy(_str + pos, str, len);_size += len;
}// 17:10
void string::erase(size_t pos, size_t len)
{assert(pos < _size);// len大于前面字符个数时,有多少删多少if (len >= _size - pos){_str[pos] = '\0';_size = pos;}else{strcpy(_str + pos, _str + pos + len);_size -= len;}
}
// s1.swap(s3)
void string::swap(string& s)
{std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);
}string string::substr(size_t pos, size_t len)
{// len大于后面剩余字符,有多少取多少if (len > _size - pos){string sub(_str + pos);return sub;}else{string sub;sub.reserve(len);for (size_t i = 0; i < len; i++){sub += _str[pos + i];}return sub;}
}
其他函数
bool string::operator<(const string& s) const{return strcmp(_str, s._str) < 0;}bool string::operator>(const string& s) const{return !(*this <= s);}bool string::operator<=(const string& s) const{return *this < s || *this == s;}bool string::operator>=(const string& s) const{return !(*this < s);}bool string::operator==(const string& s) const{return strcmp(_str, s._str) == 0;}bool string::operator!=(const string& s) const{return !(*this == s);}
void string::clear()
{_str[0] = '\0';_size = 0;
}istream& operator>> (istream& is, string& str)
{str.clear();char ch = is.get();while (ch != ' ' && ch != '\n'){str += ch;ch = is.get();}return is;
}ostream& operator<< (ostream& os, const string& str)
{for (size_t i = 0; i < str.size(); i++){os << str[i];}return os;
}
总结
string.h
#pragma once#include<iostream>
#include<assert.h>
using namespace std;namespace bit
{class string{public:typedef char* iterator;typedef const char* const_iterator;iterator begin();iterator end();const_iterator begin() const;const_iterator end() const;//string();string(const char* str = "");string(const string& s);string& operator=(const string& s);~string();const char* c_str() const;size_t size() const;char& operator[](size_t pos);const char& operator[](size_t pos) const;void reserve(size_t n);void push_back(char ch);void append(const char* str);string& operator+=(char ch);string& operator+=(const char* str);void insert(size_t pos, char ch);void insert(size_t pos, const char* str);void erase(size_t pos = 0, size_t len = npos);size_t find(char ch, size_t pos = 0);size_t find(const char* str, size_t pos = 0);void swap(string& s);string substr(size_t pos = 0, size_t len = npos);bool operator<(const string& s) const;bool operator>(const string& s) const;bool operator<=(const string& s) const;bool operator>=(const string& s) const;bool operator==(const string& s) const;bool operator!=(const string& s) const;void clear();private:// char _buff[16];char* _str;size_t _size;size_t _capacity;// //const static size_t npos = -1;// ?//const static double N = 2.2;const static size_t npos;};istream& operator>> (istream& is, string& str);ostream& operator<< (ostream& os, const string& str);
}
string.cpp
//string::string()//{// _str = new char[1]{'\0'};// _size = 0;// _capacity = 0;//}string::iterator string::begin(){return _str;}string::iterator string::end(){return _str + _size;}string::const_iterator string::begin() const{return _str;}string::const_iterator string::end() const{return _str + _size;}string::string(const char* str):_size(strlen(str)){_str = new char[_size + 1];_capacity = _size;strcpy(_str, str);}// s2(s1)string::string(const string& s){_str = new char[s._capacity + 1];strcpy(_str, s._str);_size = s._size;_capacity = s._capacity;}// s1 = s3// s1 = s1string& string::operator=(const string& s){if (this != &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(){delete[] _str;_str = nullptr;_size = _capacity = 0;}const char* string::c_str() const{return _str;}size_t string::size() const{return _size;}char& string::operator[](size_t pos){assert(pos < _size);return _str[pos];}const char& string::operator[](size_t pos) const{assert(pos < _size);return _str[pos];}void string::reserve(size_t n){if (n > _capacity){char* tmp = new char[n + 1];strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = n;}}void string::push_back(char ch){/*if (_size == _capacity){size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;reserve(newcapacity);}_str[_size] = ch;_str[_size + 1] = '\0';++_size;*/insert(_size, ch);}// "hello" "xxxxxxxxxxxxx"void string::append(const char* str){/*size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}strcpy(_str+_size, str);_size += len;*/insert(_size, str);}string& string::operator+=(char ch){push_back(ch);return *this;}string& string::operator+=(const char* str){append(str);return *this;}void string::insert(size_t pos, char ch){assert(pos <= _size);if (_size == _capacity){size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;reserve(newcapacity);}/*int end = _size;while (end >= (int)pos){_str[end + 1] = _str[end];--end;}*/size_t end = _size + 1;while (end > pos){_str[end] = _str[end - 1];--end;}_str[pos] = ch;++_size;}void string::insert(size_t pos, const char* str){assert(pos <= _size);size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}/*int end = _size;while (end >= (int)pos){_str[end + len] = _str[end];--end;}*/size_t end = _size + len;while (end > pos + len - 1){_str[end] = _str[end - len];--end;}memcpy(_str + pos, str, len);_size += len;}// 17:10void string::erase(size_t pos, size_t len){assert(pos < _size);// len大于前面字符个数时,有多少删多少if (len >= _size - pos){_str[pos] = '\0';_size = pos;}else{strcpy(_str + pos, _str + pos + len);_size -= len;}}size_t string::find(char ch, size_t pos){for (size_t i = pos; i < _size; i++){if (_str[i] == ch){return i;}}return npos;}size_t string::find(const char* sub, size_t pos){char* p = strstr(_str + pos, sub);return p - _str;}// s1.swap(s3)void string::swap(string& s){std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}string string::substr(size_t pos, size_t len){// len大于后面剩余字符,有多少取多少if (len > _size - pos){string sub(_str + pos);return sub;}else{string sub;sub.reserve(len);for (size_t i = 0; i < len; i++){sub += _str[pos + i];}return sub;}}bool string::operator<(const string& s) const{return strcmp(_str, s._str) < 0;}bool string::operator>(const string& s) const{return !(*this <= s);}bool string::operator<=(const string& s) const{return *this < s || *this == s;}bool string::operator>=(const string& s) const{return !(*this < s);}bool string::operator==(const string& s) const{return strcmp(_str, s._str) == 0;}bool string::operator!=(const string& s) const{return !(*this == s);}void string::clear(){_str[0] = '\0';_size = 0;}istream& operator>> (istream& is, string& str){str.clear();char ch = is.get();while (ch != ' ' && ch != '\n'){str += ch;ch = is.get();}return is;}ostream& operator<< (ostream& os, const string& str){for (size_t i = 0; i < str.size(); i++){os << str[i];}return os;}
相关文章:
【数据结构】string(C++模拟实现)
string构造 string::string(const char* str):_size(strlen(str)) {_str new char[_size 1];_capacity _size;strcpy(_str, str); }// s2(s1) string::string(const string& s) {_str new char[s._capacity 1];strcpy(_str, s._str);_size s._size;_capacity s._cap…...
【笔记】I/O总结王道强化视频笔记
文章目录 从中断控制器的角度来理解整个中断处理的过程复习 处理器的中断处理机制**中断驱动I/O方式** printf——从系统调用到I/O控制方式的具体实现1轮询方式下输出一个字符串(程序查询)中断驱动方式下输出一个字符串中断服务程序中断服务程序与设备驱动程序之间的关系 DMA方…...
XML XSLT:转换与呈现数据的力量
XML XSLT:转换与呈现数据的力量 XML(可扩展标记语言)和XSLT(XML样式表转换语言)是现代信息技术中不可或缺的工具,它们在数据交换、存储和呈现方面发挥着重要作用。本文将深入探讨XML和XSLT的概念、应用及其在信息技术领域的重要性。 XML:数据交换的标准 XML是一种用于…...
ES6总结
1.let和const以及与var区别 1.1 作用域 var: 变量提升(Hoisting):var 声明的变量会被提升到其作用域的顶部,但赋值不会提升。这意味着你可以在声明之前引用该变量(但会得到 undefined)。 con…...
晶体匹配测试介绍
一、晶体参数介绍 晶体的电气规格相对比较简单,如下: 我们逐一看看每个参数, FL就是晶体的振动频率,这个晶体是24.576MHz的。 CL就是负载电容,决定了晶体频率是否准确,包括外接的实际电容、芯片的等效电容以及PCB走线的寄生电容等,核心参数。 Frequency Tolerance是…...
超声波清洗机靠谱吗?适合学生党入手的四款眼镜清洗机品牌推荐!
有没有学生党还不知道双十一买什么?其实可以去看看超声波清洗机,说实话它的实用性真的很高,对于日常用于清洗眼镜真的非常合适,不仅可以帮助大家节约时间而且还能把眼镜清洗的干净透亮,接下来我就来为大家带来四款好用…...
Java生成图片_基于Spring AI
Spring AI 优势 过去,使用Java编写AI应用时面临的主要困境是没有统一且标准的封装库,开发者需自行对接各个AI服务提供商的接口,导致代码复杂度高、迁移成本大。如今,Spring AI Alibaba的出现极大地缓解了这一问题,它提…...
程序传入单片机的过程,以Avrdude为例分析
在市场上有各式各样的单片机,例如Arduino,51单片机,STM等。通常,我们都用其对应的IDE软件进行单片机的编程。这些软件既负责将程序代码转写成二进制代码,即机器语言,也负责将该二进制代码导入单片机。与此同…...
用YOLO和LLM增强的OCR
虽然最近我花了很多时间在大型语言模型 (LLM) 上进行实验,但我对计算机视觉的热情始终未减。因此,当我有机会将两者融合在一起时,我迫不及待地想要立即开始。在 Goodreads 上扫描书籍封面并将其标记为已读一直感觉有点神奇,我很兴…...
开源的云平台有哪些?
开源云平台为用户提供了构建、管理和运行云基础设施及应用的能力,同时允许社区参与开发和改进。以下是一些知名的开源云平台: 1. OpenStack 简介:OpenStack:一个广泛使用的开源云平台,它由多个组件组成,提…...
Spring Boot学习资源库:微服务架构的加速器
3 系统分析 3.1可行性分析 在进行可行性分析时,我们通常根据软件工程里方法,通过四个方面来进行分析,分别是技术、经济、操作和法律可行性。因此,在基于对目标系统的基本调查和研究后,对提出的基本方案进行可行性分析。…...
Pi4+wfb-ng+8812au
sudo apt update将如下文件拷入树莓派4 linux-6f921e98008589258f97243fb6658d09750f0a2f.tar.gz libsodium.zip rtl8812au.zip wfb-ng_Pi4_2.zip 安装libsodium unzip libsodium.zip cd libsodium ./configure make && make check sudo make install#安装8812AU驱动 …...
基于单片机的非接触智能测温系统设计
本设计主要由单片机STC8A8K64S4A12、OLED显示屏、非接触式测温模块MLX9061、无线通讯模块ESP8266以及声光报警模块等构成。系统通过非接触式测温模块MLX9061测量当前人员温度,温度通过OLED显示屏进行实时显示,当被测温度高于阈值,声光报警模块…...
第二十三篇:网络拥塞了,TCP/IP如何解决的?
一.显示拥塞通知 当发生网络拥塞时,发送主机应该减少数据包的发送量。作为IP上层协议,TCP虽然也能控制网络拥塞,不过它是通过数据包的实际损坏情况来判断是否发生拥塞。然而这种方法不能在数据包损坏之前减少数据包的发送量。 为了解决这个…...
登录注册静态网页实现(HTML,CSS)
实现效果图 实现效果 使用HTML编写页面结构,CSS美化界面,点击注册,跳转到注册界面,均为静态网页,是课上的一个小作业~ 使用正则表达式对输入进行验证,包括邮箱格式验证,用户名格式验证。 正则…...
基于FPGA的以太网设计(二)
一.以太网硬件架构概述 前文讲述了以太网的一些相关知识,本文将详细讲解以太网的硬件架构 以太网的电路架构一般由MAC、PHY、变压器、RJ45和传输介质组成,示意图如下所示: PHY:Physical Layer,即物理层。物理层定义了…...
OJ在线评测系统 后端微服务架构 注册中心 Nacos入门到启动
注册中心 服务架构中的注册中心是一个关键组件,用于管理和协助微服务之间的通信。注册中心的主要职责是服务的注册和发现,确保各个微服务能够相互找到并进行调用。 主要功能: 服务注册:微服务在启动时,将自身信息&am…...
升级到Ubuntu 24.04遇到的问题
升级过程中被别人关机重启到windows了,再启动到linux接着升级,还好能运行。但出现了些问题。 1.网络无法访问,发现是dns问题。最后在/etc/systemd/resov.conf文件中添加nameserver sudo nano /etc/systemd/resolv.conf cd /etc sudo ln -s …...
提示词格式化
利用jinja2,对提示词进行格式输出。以下是qwen2中tokenizer_config.json文件中的chat_template模块定义的提示词转换方式。 (1)查看qwen2的chat_template {"add_prefix_space": false,"added_tokens_decoder": {"…...
JAVA八股文1
1.Java 基础 1.1 语法基础 封装 利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体。数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保留一些对外接口使之与外部发生联系。用户无需知道对象内…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
