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

【STL】String的底层构造

1.String类对象的构造(后面有每一个接口的实现)

#define _CRT_SECURE_NO_WARNINGS 1
#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);
}

2.String类常见的构造方式

void test_string1()
{// 常用string s1;string s2("hello world");string s3(s2);// 不常用 了解string s4(s2, 3, 5);string s5(s2, 3);string s6(s2, 3, 30);string s7("hello world", 5);string s8(10, 'x');cout << s1 << endl;cout << s2 << endl;cout << s3 << endl;cout << s4 << endl;cout << s5 << endl;cout << s6 << endl;cout << s7 << endl;cout << s8 << endl;cin >> s1;cout << s1 << endl;
}

3.String的隐式类型转换与构造

void test_string2()
{string s1("hello world"); //构造string s2 = "hello world"; //隐式类型转换const string& s3 = "hello world";// 临时对象具有常性,加const}

4.String类的基本操作函数

void test_string3()
{string s1("hello world");cout << s1.size() << endl;
//capacity 比 实际空间少一个,有一个多的是预留给\0cout << s1.capacity() << endl;cout << s1.max_size() << endl;
}

5.String的三种遍历方式

        5.1  :使用[]来完成遍历

        

string s1 = "hello world";for (int i = 0; s1[i]; i++){cout << s1[i] << " ";}cout << endl;

        5.2 : 使用迭代器完成遍历

        

string::iterator it1 = s1.begin();while (it1 != s1.end()) { cout << *it1 << " ";++it1;}cout << endl;cout << typeid(it1).name() << endl

        5.3 :使用auto 来完成遍历

//遍历方式3:范围for// 底层:就是迭代器for (auto e : s1) {cout << e << " ";}

6.String的逆置 - reverse

void test_string5() //反向迭代器
{string s1("hello world");string::const_iterator it1 = s1.begin();//auto it1 = s1.begin();while (it1 != s1.end()){//*it1 += 3;// 不能修改cout << *it1 << " ";++it1;}string s2("hello world");string::reverse_iterator it2 = s2.rbegin();while (it2 != s2.rend()) {*it2 += 3;cout << *it2 << " ";++it2;}
}

7.String的sort 排序

void test_string6()
{string s1("hello world");cout << s1 <<endl;//按字典序排序sort(s1.begin(), s1.end());//第一个和最后一个参与排序sort(++s1.begin(), --s1.end());//前五个排序sort(s1.begin(), s1.begin() + 5);cout << s1 << endl;
}

8.string 的插入删除

void push_back(char ch);
void append(const char* str);
void insert(size_t pos, char ch);
void insert(size_t pos, const char* str);
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;
}

8.2:在pos位置插入字符串

        

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;
}

对于push_back,直接复用insert

void string::push_back(char ch)
{insert(_size, ch);
}

8.3 earse的实现

        

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;}
}

9.String中查找一个字符与字符串(Find 的实现)

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;
}

10.resize与reserve

        

void test_string11()
{string s1;s1.resize(5, '0'); //初始值cout << s1 << endl;// 再扩容s1.reserve(100);cout << s1.size() << "  " << s1.capacity() << endl;//reserve 在vs下不会缩容,没有规定s1.reserve(20);cout << s1.size() << "  " << s1.capacity() << endl;s1.resize(10);cout << s1.size() << "  " << s1.capacity() << endl;s1.resize(120);cout << s1.size() << "  " << s1.capacity() << endl;//由此发现resize影响capacity、size(当再开辟空间大于原先capacity才会影响capacity), reserve不影响size//插入(空间不够扩容)string s2("hello world");s2.resize(20, 'x'); //不会清掉之前的字符,在后面填写cout << s2 << endl;// 删除s2.resize(5); 
}

11.c_str的比较

void test_string13()
{string a = "abc";string b = a;//a.c_str() == b.c_str()比较的是存储字符串位置的地址,// a和b是两个不同的对象,内部数据存储的位置也不相同,因此不相等if (a.c_str() == b.c_str())cout << "True" << endl;else cout << "False" << endl;
}

12.string的总接口的实现

        接口:

#define _CRT_SECURE_NO_WARNINGS 1
#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);
}

接口的实现:

#include"string.h"namespace bit
{const size_t string::npos = -1;//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;}// 21:10string::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;}
}

13.补充:大小写转换

transform(s.begin(),s.end(),s.begin(),::tolower);
transform(s.begin(),s.end(),s.begin(),::toupper);

13.2 substr取子串

str = str.substr(cnt); //取从cnt下标开始一直到结束的所有字符str = str.substr(cnt,m); //取从cnt下标开始的m个字符

13.3 字符串与数字的相互转化

a、字符串转数字1 .string s="12";2 .int y=stoi(s);b、数字转字符串string x=to_string(12);

14.string的相关题型

1.字符串相加

2.仅仅反转字母

3.字符串中第一个唯一字符

4.字符串中最后一个单词长度

5.验证回文串

6.字符串相加

7.反转字符串II

8.反转字符串III

9.字符串相乘

10.找出字符串中第一个只出现一次的字符

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Executable Code Actions Elicit Better LLM Agents
  • 国球荣耀背后的笑与泪——陈梦夺冠现象有感
  • 银河麒麟V10 审计工具 auditd 内存泄漏问题
  • Stable Diffusion绘画 | 图生图-基础使用介绍—提示词反推
  • 监控员工电脑的软件有哪些?四款监控员工电脑的软件分享!
  • fatal error: concurrent map iteration and map write - 关于Go中并发访问Map的操作
  • android compose设置圆角不起作用
  • Visual Studio 和 VSCode 哪个好?
  • mac下载exe后不自动打开虚拟机
  • 全自动真空拌馅机 肠类肉丸类馅料搅拌机:
  • 系统 hap
  • 2021年庐阳区青少年信息学科普日真题- 跳跃(jump)
  • 代码随想录算法训练营第三十二天 | 动态规划 part01
  • 《学会 SpringMVC 系列 · 剖析出参处理》
  • MacOS 中 Office 历史记录一键清理
  • hexo+github搭建个人博客
  • [译] 怎样写一个基础的编译器
  • 【Linux系统编程】快速查找errno错误码信息
  • HTTP中的ETag在移动客户端的应用
  • JAVA 学习IO流
  • Java比较器对数组,集合排序
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • MySQL QA
  • ng6--错误信息小结(持续更新)
  • Spring核心 Bean的高级装配
  • 百度地图API标注+时间轴组件
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 给自己的博客网站加上酷炫的初音未来音乐游戏?
  • 欢迎参加第二届中国游戏开发者大会
  • 判断客户端类型,Android,iOS,PC
  • 浅谈web中前端模板引擎的使用
  • 因为阿里,他们成了“杭漂”
  • 转载:[译] 内容加速黑科技趣谈
  • MPAndroidChart 教程:Y轴 YAxis
  • ​学习一下,什么是预包装食品?​
  • #include
  • (C++17) optional的使用
  • (ISPRS,2023)深度语义-视觉对齐用于zero-shot遥感图像场景分类
  • (六)激光线扫描-三维重建
  • (每日持续更新)jdk api之StringBufferInputStream基础、应用、实战
  • (南京观海微电子)——I3C协议介绍
  • (七)理解angular中的module和injector,即依赖注入
  • (十六)一篇文章学会Java的常用API
  • (四)opengl函数加载和错误处理
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .bat文件调用java类的main方法
  • .net MVC中使用angularJs刷新页面数据列表
  • .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?
  • .Net的DataSet直接与SQL2005交互
  • .NET未来路在何方?
  • @JSONField或@JsonProperty注解使用
  • @JsonFormat与@DateTimeFormat注解的使用
  • @SuppressWarnings(unchecked)代码的作用
  • [20170705]diff比较执行结果的内容.txt
  • [2018][note]用于超快偏振开关和动态光束分裂的all-optical有源THz超表——