#pragma once #include #include #include namespace Lenyiin { // 实现一个支持增删查改的 string class String { public: // 迭代器 typedef char *iterator; typedef const char *const_iterator; typedef char *riterator; typedef const char *const_riterator; iterator begin() // 返回首地址 { return _str; } iterator end() // 返回尾地址 { return _str + _size; } const_iterator begin() const { return _str; } const_iterator end() const { return _str + _size; } riterator rbegin() { return _str + _size - 1; } riterator rend() { return _str - 1; } const_riterator rbegin() const { return _str + _size - 1; } const_riterator rend() const { return _str - 1; } public: //// 默认构造函数:创建一个空字符串 // String() // : _str(nullptr), _size(0), _capacity(0) //{ // } //// 带参数的构造函数:从C风格字符串创建String对象 // String(const char* str) { // if (str) { // _size = _capacity = strlen(str); // _str = new char[_size + 1]; // 分配内存,+1是为了存储终止符'\0' // strcpy(_str, str); // 将字符串内容复制到data指向的内存 // } // else { // _str = nullptr; // _size = _capacity = 0; // } // } // 进阶写法 // 默认构造函数 String(const char *str = "") // 默认构造函数 : _str(new char[strlen(str) + 1]), _size(strlen(str)), _capacity(_size) { strcpy(_str, str); } // 拷贝构造函数:深拷贝 // String(const String& s) // 拷贝构造函数 // : _str(new char[s._capacity + 1]), _size(s._size), _capacity(s._capacity) //{ // strcpy(_str, s._str); //} // 进阶写法 // 拷贝构造 复用默认构造 String(const String &s) : String(s._str) { } // 赋值运算 // 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; //} // 进阶写法 // 赋值运算符重载 void Swap(String &s) { std::swap(_str, s._str); std::swap(_size, s._size); std::swap(_capacity, s._capacity); } String &operator=(String s) { this->Swap(s); return *this; } String &operator=(const char *str) { String s(str); this->Swap(s); return *this; } // 移动构造函数 String(String &&s) noexcept : _str(s._str), _size(s._size), _capacity(s._capacity) { s._str = nullptr; s._size = s._capacity = 0; } // 移动赋值运算符 String &operator=(String &&s) noexcept { if (this != &s) { delete[] _str; // 释放当前对象的内存 _str = s._str; // 接管资源 _size = s._size; _capacity = s._capacity; s._str = nullptr; // 将other对象重置为默认状态 s._size = s._capacity = 0; } return *this; } // 重载 [] 运算符 char &operator[](size_t pos) { assert(pos < _size); return _str[pos]; } const char &operator[](size_t pos) const { assert(pos < _size); return _str[pos]; } // 获取私有成员 size_t size() const // 获取有效字符个数 { return _size; } size_t capacity() const // 获取有效容量 { return _capacity; } const char *c_str() const // 返回字符串 { return _str; } // 析构函数 ~String() { delete[] _str; _str = nullptr; _size = _capacity = 0; } // 开辟空间 void reserve(size_t newcapacity) { if (newcapacity > _capacity) { char *newstr = new char[newcapacity + 1]; strcpy(newstr, _str); delete[] _str; _str = newstr; _capacity = newcapacity; } } // 设置指定大小, 并初始化 void resize(size_t newsize, char ch = '\0') { if (newsize < _size) { _size = newsize; _str[_size] = '\0'; } else { if (newsize > _capacity) { reserve(newsize); } for (size_t i = _size; i < newsize; i++) { _str[i] = ch; } _size = newsize; _str[_size] = '\0'; } } // 尾插 void push_back(char ch) // 尾插一个字符 { if (_size == _capacity) { size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2; reserve(newcapacity); } _str[_size++] = ch; _str[_size] = '\0'; } // 追加 void append(const char ch) { push_back(ch); } void append(const char *str) // 追加一个字符串 { size_t len = strlen(str); if (_size + len > _capacity) { reserve(_size + len); } strcpy(_str + _size, str); _size += len; } void append(const String &s) // 追加一个对象 { append(s._str); } // 运算符 += 重载 String &operator+=(const char ch) { this->push_back(ch); return *this; } String &operator+=(const char *str) { this->append(str); return *this; } String &operator+=(const String &s) { append(s); return *this; } // 任意位置插入字符 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; } _str[pos] = ch; ++_size; return *this; } // 任意位置插入字符串 String &insert(size_t pos, const char *str) { assert(pos <= _size); // 1. 如果空间不够就扩容 size_t len = strlen(str); if (_size + len > _capacity) { reserve(_size + len); } // 2. 挪动数据 int end = _size; while (end >= (int)pos) { _str[end + len] = _str[end]; --end; } // 3. 插入数据 strncpy(_str + pos, str, len); _size += len; return *this; } // 任意位置插入一个对象 String &insert(size_t pos, const String &s) { return insert(pos, s._str); } // 删除 String &erase(size_t pos = 0, size_t len = npos) { assert(pos < _size); if (len >= _size - pos) { _str[pos] = '\0'; _size = pos; } else { while (pos <= _size - len) { _str[pos] = _str[pos + len]; ++pos; } _size -= len; } return *this; } // 尾删 void pop_back() { assert(_size > 0); --_size; _str[_size] = '\0'; } // 运算符 < 重载 bool operator<(const String &s) { int ret = strcmp(_str, s._str); return ret < 0; } // 运算符 == 重载 bool operator==(const String &s) { int ret = strcmp(_str, s._str); return ret == 0; } // 运算符 <= 重载 bool operator<=(const String &s) { return *this < s || *this == s; } // 运算符 > 重载 bool operator>(const String &s) { int ret = strcmp(_str, s._str); return ret > 0; } // 运算符 >= 重载 bool operator>=(const String &s) { return !(*this < s); } // 运算符 != 重载 bool operator!=(const String &s) { return !(*this == s); } // 查找字符 size_t find(char ch, size_t pos = 0) const { for (size_t i = pos; i < _size; i++) { if (_str[i] == ch) { return i; } } return npos; } // 查找字符串 size_t find(const char *str, size_t pos = 0) const { char *p = strstr(_str, str); if (p == nullptr) { return npos; } else { return p - _str; } } // 查找对象 size_t find(const String &s, size_t pos = 0) const { return find(s._str, pos); } // 反向查找字符串 size_t rfind(char ch, size_t pos = npos) const { if (pos == npos) { pos = _size - 1; } for (int i = pos; i >= 0; i--) { if (_str[i] == ch) { return i; } } return npos; } // 反向查找字符串 size_t rfind(const char *str, size_t pos = npos) { size_t len = strlen(str); if (len > _size) { return npos; } if (pos >= _size) { pos = _size - 1; } for (size_t i = pos; i != npos; i--) { if (strncmp(_str + i, str, len) == 0) { return i; } } return npos; } String substr(size_t pos = 0, size_t len = npos) const { assert(pos < _size); if (len == npos || len + pos > _size) { len = _size - pos; } char *buffer = new char[len + 1]; strncpy(buffer, _str + pos, len); buffer[len] = '\0'; return String(buffer); } // 清空 void clear() { _size = 0; _str[_size] = '\0'; } private: char *_str; size_t _size; // 记录已经存储了多少有效字符 size_t _capacity; // 记录能存储多少有效字符 '\0' 结尾 但不作为有效字符 public: static size_t npos; // size_t -> unsigned long long -1 是一个极大的数 }; size_t String::npos = -1; std::ostream &operator<<(std::ostream &_cout, const String &s) { for (size_t i = 0; i < s.size(); i++) { _cout << s[i]; } return _cout; } std::istream &operator>>(std::istream &_cin, String &s) { while (true) { char ch; //_cin >> ch; ch = _cin.get(); // if (ch == '\n') // 通过换行分割 if (ch == ' ' || ch == '\n') { break; } else { s += ch; } } return _cin; } }