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

【C++课程学习】:string的模拟实现

🎁个人主页:我们的五年

🔍系列专栏:C++课程学习

🎉欢迎大家点赞👍评论📝收藏⭐文章

 

目录

一.string的主体框架:

二.string的分析:

🍔构造函数和析构函数:

🍔迭代器:

🍔赋值运算符重载:

🍔空间扩容:

🍔尾插:

🍔获取_str,_capacity,_size:

 🍔[]重载,随机访问:

🍔在结尾追加字符串

🍔在指定位置插入和删除字符串:

🍔交换:

🍔获取子串和寻找元素和字符串:

🍔运算符重载:

🍔流插入和流提取重载:


通过对string的模拟实现,可以对string有更深的理解和认识,大概知道底层的逻辑,以后出现什么问题可以更好的解决。对学习以后的容器也有很大的帮助。

 

一.string的主体框架:

1.迭代器        2.运算符重载        3.

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<iostream>
#include<cstring>
#include<assert.h>
#include<algorithm>using namespace std;namespace bit {class string {public://迭代器typedef char* iterator;typedef const char* const_iterator;iterator begin();const_iterator begin()const;iterator end();const_iterator end()const;//构造函数string(size_t capacity = 4);string(const string& s);string(const char* str);string& operator=(const string& str);//析构函数~string();//异地扩容void reserve(size_t newcapacity);//尾插数据void push_back(char c);const char* c_str()const;size_t size()const;size_t capacity()const;char& operator[](size_t pos);const char& operator[](size_t pos)const;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);void swap(string& s);string substr(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);//运算符重载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;//对sring进行清理void clear();private:const static size_t npos = -1;char* _str;//有效大小size_t _size;//空间的容量size_t _capacity;};//重载流插入和流提取istream& operator>> (istream& is, string& str);ostream& operator<< (ostream& os, const string& str);
}

二.string的分析:

🍔构造函数和析构函数:

构造函数常用的是三个,普通构造,拷贝构造,用const char*类型进行构造。

	//capacity表示要提前开的空间大小string::string(size_t capacity):_str(new char[capacity + 1]), _capacity(capacity), _size(0){_str[0] = '\0';}//拷贝构造string::string(const string& s){_capacity = s._capacity;_size = s._size;_str = new char[_capacity + 1];strcpy(_str, s._str);}string::string(const char* str){size_t length = strlen(str);_str = new char[length + 1];_capacity = _size = length;strcpy(_str, str);}string::~string(){delete[] _str;_str = nullptr;_capacity = _size = 0;}

🍔迭代器:

		//迭代器typedef char* iterator;typedef const char* const_iterator;iterator begin();const_iterator begin()const;iterator end();const_iterator end()const;

🍔赋值运算符重载:

	string& string::operator=(const string& str){if (str._capacity > _capacity)reserve(str._capacity);strcpy(_str, str._str);return *this;}

🍔空间扩容:

	void string::reserve(size_t newcapacity){//先判断是否需要扩容//如果newcapacity小于等于,就不会扩,也不会缩容if (newcapacity <= _capacity)return;char* p = new char[newcapacity + 1];_capacity = newcapacity;strcpy(p, _str);delete[] _str;_str = p;}

🍔尾插:

	void string::push_back(char c){if (_size == _capacity){//不能直接乘以两倍,_capacity可能为0,乘二还是为0size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;reserve(newcapacity);}_str[_size] = c;_size++;}

🍔获取_str,_capacity,_size:

	const char* string:: c_str()const{return _str;}size_t string::size()const{return _size;}size_t string::capacity()const{return _capacity;}

 🍔[]重载,随机访问:

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

🍔在结尾追加字符串

	void string::append(const char* s){size_t length = strlen(s);if(_size + length > _capacity)reserve(_size + length);//strcat(_str, s);_size += length;}

🍔在指定位置插入和删除字符串:

	void string::insert(size_t pos, char ch){assert(pos >= 0 && pos <= _size);if (_size == _capacity)reserve(_capacity * 2);size_t end = _size + 1;while (end > pos){_str[end] = _str[end - 1];end--;}_size++;_str[pos] = ch;}void string::insert(size_t pos, const char* str){assert(pos >= 0 && pos <= _size);size_t length = strlen(str);if (length + _size > _capacity)reserve(length + _size);for (size_t i = _size - 1; i >= pos; i--)_str[i + length] = _str[i];_str[_size + length] = 0;for (size_t i = 0; i < length; i++)_str[i + pos] = str[i];}void string::erase(size_t pos, size_t len){assert(pos >= 0 && pos < _size - 1);if (len>=_size-pos){_str[pos] = '\0';_size = pos;}else{strcpy(_str + pos, _str + pos + len);_size -= len;}}

🍔交换:

	void string::swap(string& s){std::swap(s._capacity, _capacity);std::swap(s._size, _size);std::swap(s._str, _str);}

🍔获取子串和寻找元素和字符串:

	string string::substr(size_t pos, size_t len){assert(pos >= 0 && pos < _size);if (len > _size - pos){bit::string substr(_str + pos);return substr;}else{bit::string substr(len);for (size_t i = pos; i < pos+len; i++)substr += _str[i];return substr;}}size_t string::find(char ch, size_t pos){for (size_t i = 0; i < pos; i++){if (_str[i] == ch)return i;}return -1;}size_t string::find(const char* str, size_t pos){char* p = strstr(_str + pos, str);return p - _str;}

🍔运算符重载:

	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 || (*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);}string& string::operator+=(char ch){insert(_size, ch);return *this;}string& string::operator+=(const char* str){insert(_size, str);return *this;}

🍔流插入和流提取重载:

	istream& operator>>(istream& is, string& s){s.clear();char it = is.get();while (it != ' ' && it != '\n'){s += it;it = is.get();}return is;}ostream& operator<<(ostream& os, const string& s){for (size_t i = 0; i < s.size(); i++)os << s[i];return os;}

 


http://www.mrgr.cn/news/66915.html

相关文章:

  • 网页版五子棋—— WebSocket 协议
  • Java 实现接口幂等的九种方法:确保系统稳定性与数据一致性
  • 【报错解决】
  • 62-Java-面试专题(1)__基础
  • 【Android 系统中使用CallStack类来追踪获取和操作调用栈信息】
  • 【深入浅出】深入浅出Bert(附面试题)
  • 防患于未然才是预警大屏的意义所在,看它是如何做的?
  • java-web-day14-项目属性配置和bean的管理
  • docker 常用方法
  • 编译cartographer和cartographer_ros 过程
  • 超好用的运维终端 NuShell
  • 《纺织报告》是什么级别的期刊?是正规期刊吗?能评职称吗?
  • 再也不怕丢失灵感:Heynote,让开发者的笔记更高效
  • 【开发工具】解决Ubuntu首次打开vscode工作区字体小的问题
  • UCLA、MIT数学家推翻39年经典数学猜想!AI证明卡在99.99%,人类最终证伪
  • 检索增强和知识冲突学习笔记
  • 企业防泄密指南|如何防止员工泄密?5个常用的防泄密方案详细说明,赶紧去试!
  • spark人才推荐系统-计算机设计毕业源码19842
  • 智能存储解决方案:探索 TDengine 的多级存储功能
  • 高亚科技签约酸动力,助力研发管理数字化升级
  • LangChain Ollama实战文献检索助手(一)环境配置和输入输出解析
  • 【C++】踏上C++学习之旅(五):auto、范围for以及nullptr的精彩时刻(C++11)
  • 滑动窗口算法
  • sql专题 之 常用命令
  • Java学习路线:Maven(一)认识Maven
  • 程序员开发速查表