- #include
- #include
- #include
- #include
- using namespace std;
-
- namespace zwx
- {
- class string
- {
- public:
- //string迭代器就是指针
- typedef char* iterator;
- iterator begin()
- {
- return _str;
- }
- iterator end()
- {
- return _str + _size;
- }
-
- typedef const char* const_iterator;//*在const之后,表示char*指向的内容不可修改
- const_iterator begin() const //只能读,不能写
- {
- return _str;
- }
- const_iterator end() const
- {
- return _str + _size;
- }
-
- //构造函数
- string(const char* str = "")
- {
- _size = strlen(str);
- _capacity = _size;
- _str = new char[_capacity + 1];
-
- strcpy(_str, str);
- }
-
- // //传统写法 拷贝构造
- //string(const string& s)
- // :_str(new char[s._capacity+1])
- // , _size(s._size)
- // , _capacity(s._capacity)
- //{
- // strcpy(_str, s._str);
- //}
- operator=
- //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& tmp)
- {
- ::swap(_str, tmp._str);//::调用全局std中的swap
- ::swap(_size, tmp._size);
- ::swap(_capacity, tmp._capacity);
- }//全局中的swap函数会调用拷贝构造(自定义类型),string中的swap只进行成员变量的交换
-
- string(const string& s)
- :_str(nullptr)//可以delete nullptr,但是不能delete野指针
- , _size(0)
- , _capacity(0)
- {
- string tmp(s._str);//调用构造函数
- swap(tmp); //this->swap(tmp);
- }
-
- string& operator=(string s)//s顶替tmp做打工人
- {
- swap(s);
- return *this;
- }
-
- ~string()
- {
- delete[] _str;//可以delete nullptr,不能delete一个随机的空间
- _str = nullptr;
- _size = _capacity = 0;
- }
-
- const char* c_str() const
- {
- return _str;
- }
-
- size_t size() const//返回的是一个内置类型的数字
- {
- return _size;
- }
-
- size_t capacity() const
- {
- return _capacity;
- }
-
- const char& operator[](size_t pos) const
- {
- assert(pos < _size);
- return _str[pos];
- }
-
- char& operator[](size_t pos)//可以修改
- {
- assert(pos < _size);
- return _str[pos];
- }
-
- void reserve(size_t n)
- {
- if (n > _capacity)
- {
- char* tmp = new char[n + 1];
- strcpy(tmp, _str);
- delete[] _str;
- _str = tmp;
- _capacity = n;
- }
- }
-
- void resize(size_t n, char ch = '\0')
- {
- if (n > _size)
- {
- // 插入数据
- reserve(n);
- for (size_t i = _size; i < n; ++i)
- {
- _str[i] = ch;
- }
- _str[n] = '\0';
- _size = n;
- }
- else
- {
- // 删除数据
- _str[n] = '\0';
- _size = n;
- }
- }
-
- void push_back(char ch)
- {
- //满了就扩容
- if (_size == _capacity)
- {
- reserve(_capacity == 0 ? 4 : _capacity * 2);
- }
- _str[_size] = ch;
- ++_size;
- _str[_size] = '\0';
- }
-
- void append(const char* str)
- {
- size_t len = strlen(str);
- // 满了就扩容
- if (_size + len > _capacity)
- {
- reserve(_size+len);//容量刚好够用
- }
- strcpy(_str + _size, str);
- //strcat(_str, str); 需要找\0,效率低
- _size += len;
- }
-
- string& operator+=(char ch)
- {
- push_back(ch);
- return *this;
- }
-
- string& operator+=(const char* str)
- {
- append(str);
- return *this;
- }
-
- string& insert(size_t pos, char ch)
- {
- assert(pos <= _size);//pos前面插入
- if (_size == _capacity)
- {
- reserve(_capacity == 0 ? 4 : _capacity * 2);
- }
- size_t end = _size + 1;
- while (end > pos)
- {
- _str[end] = _str[end - 1];
- --end;
- }
-
- _str[pos] = ch;
- ++_size;
- return *this;
- }
-
- string& insert(size_t pos, const char* str)
- {
- assert(pos <= _size);
- size_t len = strlen(str);
- if (_size + len > _capacity)
- {
- reserve(_size + len);
- }
-
- size_t end = _size + len;
- while (end >= pos + len)
- {
- _str[end] = _str[end - len];
- --end;
- }
-
- strncpy(_str + pos, str, len);
- _size += len;
-
- return *this;
- }
-
- void erase(size_t pos, size_t len = npos)
- {
- assert(pos < _size);
-
- if (len == npos || pos + len >= _size)
- {
- _str[pos] = '\0';
- _size = pos;
- }
- else
- {
- strcpy(_str + pos, _str + pos + len);
- _size -= len;
- }
- }
-
- void clear()
- {
- _str[0] = '\0';
- _size = 0;//capacity不需要改变
- }
-
- size_t find(char ch, size_t pos = 0) const
- {
- assert(pos < _size);
-
- for (size_t i = pos; i < _size; ++i)
- {
- if (ch == _str[i])
- {
- return i;
- }
- }
-
- return npos;
- }
-
- size_t find(const char* sub, size_t pos = 0) const
- {
- assert(sub);
- assert(pos < _size);
- const char* ptr = strstr(_str + pos, sub);
- if (ptr == nullptr)
- {
- return npos;
- }
- else
- {
- return ptr - _str;
- }
- }
-
- string substr(size_t pos, size_t len = npos) const
- {
- assert(pos < _size);
- size_t realLen = len;
- if (len == npos || pos + len > _size)
- {
- realLen = _size - pos;
- }
- string sub;
- for (size_t i = 0; i < realLen; ++i)
- {
- sub += _str[pos + i];
- }
- return sub;
- }
-
- bool operator>(const string& s) const
- {
- return strcmp(_str, s._str) > 0;
- }
-
- bool operator==(const string& s) const
- {
- return strcmp(_str, s._str) == 0;
- }
-
- bool operator>=(const string& s) const
- {
- return *this > s || *this == s;
- }
-
- bool operator<=(const string& s) const
- {
- return !(*this > s);
- }
-
- bool operator<(const string& s) const
- {
- return !(*this >= s);
- }
-
- bool operator!=(const string& s) const
- {
- return !(*this == s);
- }
- private:
- char* _str;//指向字符串所在的空间
- size_t _size; //声明顺序为定义和初始化顺序
- size_t _capacity;//存储有效字符串的个数(不包括字符 '\0')
-
- public:
- // const static 语法特殊处理 --直接可以当成定义初始化
- const static size_t npos = -1;
- };
-
-
- //没有访问类中的私有,不需要实现友元
- //返回ostream& 实现连续插入
- ostream& operator<<(ostream& out, const string& s)
- {
- for (size_t i = 0; i < s.size(); ++i)
- {
- out << s[i];
- }
-
- return out;
- }
-
- istream& operator>>(istream& in, string& s)
- {
- s.clear();//与std库中的string一致
- char ch;
- ch = in.get();// 从输入流中提取字符
- const size_t N = 32;
- char buff[N];
- size_t i = 0;
- while (ch != ' ' && ch != '\n')
- {
- buff[i++] = ch;//避免每次都+=到s中 防止频繁的扩容
- if (i == N - 1)
- {
- buff[i] = '\0';
- s += buff;
- i = 0;
- }
- ch = in.get();
- }
- buff[i] = '\0';
- s += buff;
- return in;
- }
- }