C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数, 但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。在OJ中,有关字符串的题目基本以string类的形式出现,而且在常规工作中,为了简单、方便、快捷,基本 都使用string类,很少有人去使用C库中的字符串操作函数。为了增加自己对于string的理解,自己将模仿库中string类有的方法,设计一个简单的string类。其中类成员包括以下:
- class string
- {
-
- private:
-
- char* _str;//字符串首地址
-
- size_t _capacity;//字符串容量
-
- size_t _size;//有效数据的个数
-
- public:
-
- typedef char* iterator;
- }
我主要会实现string中经常会用到的方法,若大家想要了解更多关于string的细节,可以登录这个C++查询网站https://cplusplus.com/reference/自行查询。下面是一些常用方法以及代码片段,可能前面出现的方法会用到后面出现的方法的实现,若有疑问可以看最后面的完整代码
正向迭代器
- iterator begin()
- {
- return _str;
- }
-
- iterator end()
- {
- return _str + _size;
- }
+=
- string& operator+=(char c)
- {
- if (_size == _capacity)
- {
- _capacity = _capacity == 0 ? 4 : 2 * _capacity;
- char* tmp = new char[_capacity +1];
- strcpy(tmp, _str);
- delete[] _str;
- _str = tmp;
- }
-
- _str[_size] = c;
- _str[_size + 1] = '\0';
- _size++;
-
- return *this;
- }
-
- string& operator+=(const char* str)
- {
- append(str);
- return *this;
- }
push_back(尾插)
- void push_back(char c)
- {
- *this += c;
- }
append(在字符串末尾追加)
- void append(const char* str)
- {
- int i = 0;
- while (str[i])
- {
- push_back(str[i]);
- i++;
- }
- }
clear(清除掉字符串的数据)
- void clear()
- {
- _size = 0;
- _str[0] = '\0';
- }
swap(交换两个字符串的内容)
- void swap(string& s)
- {
- std::swap(_str,s._str);
- std::swap(_size, s._size);
- std::swap(_capacity, s._capacity);
- }
c_str(返回字符串的首地址)
- const char* c_str()const
- {
- return _str;
- }
resize(将字符串设定为指定大小,字符串占满所开辟的空间)
- void resize(size_t n, char c = '\0')
- {
- if (n > _capacity)
- {
- reserve(n);
- for (int i = _size; i < _capacity; i++)
- {
- _str[i] = c;
- }
- _size = _capacity;
- }
- else
- {
- _size = n;
- }
- }
reserve(预开辟出空间,字符串还是原来的大小(一般不缩容))
- void reserve(size_t n)
- {
- if (n > _capacity)
- {
- _capacity = n;
- char* tmp = new char[_capacity + 1];
- strcpy(tmp, _str);
- delete[] _str;
- _str = tmp;
- }
- }
find(返回字符c在string中第一次出现的位置/返回子串s在string中第一次出现的位置)
- size_t find(char c, size_t pos = 0) const
- {
- for (size_t i = pos; i < _size; i++)
- {
- if (_str[i] == c)
- return i;
- }
- return std::string::npos;
- }
- size_t find(const char* s, size_t pos = 0) const
- {
- const char* ptr = std::strstr(_str + pos, s);
-
- if (ptr == nullptr)
- return std::string::npos;
- else
- {
- return ptr - _str;
- }
- }
insert(在pos位置上插入字符c/字符串str,并返回该字符的位置)
- string& insert(size_t pos, char c)
- {
- if (_size == _capacity)
- {
- reserve(_capacity == 0 ? 4 : 2 * _capacity);
- }
- size_t end = _size - 1;
- while (end >= pos)
- {
- _str[end + 1] = _str[end];
- end--;
- }
- _str[pos] = c;
- return *this;
- }
-
- string& insert(size_t pos, const char* str)
- {
- int len = 0;
- while (str[len++]);
- if (_size + len > _capacity)
- {
- reserve(_size + len);
- }
-
- memmove(_str + pos + len, _str + pos, len * sizeof(char));
-
- for (int i = pos; i < pos + len; i++)
- {
- _str[i] = str[i - pos];
- }
- _size += len;
- return *this;
- }
erase(删除pos位置上的元素,并返回该string)
- string& erase(size_t pos, size_t len)
- {
- memmove(_str + pos, _str + pos + len, (_size - pos-len) * sizeof(char));
- _size -= len;
- return *this;
- }
- //string.h
- #pragma once
- #define _CRT_SECURE_NO_WARNINGS 1
- #include
- #include
- //using namespace std;
-
- namespace sxb
- {
-
- class string
- {
-
- friend std::ostream& operator<<(std::ostream& _cout, const string& s);
-
- friend std::istream& operator>>(std::istream& _cin, string& s);
- private:
-
- char* _str;
-
- size_t _capacity;
-
- size_t _size;
-
- public:
-
- typedef char* iterator;
-
- public:
-
- string(const char* str = "")
- {
- //_str = str;
- int len = 0;
- while(str[len] != ' ' && str[len] != '\0')
- {
- len++;
- }
- _str = new char[len + 1];
- for (int i = 0; i < len; i++)
- {
- _str[i] = str[i];
- }
- _str[len] = '\0';
- _capacity = len;
- _size = len;
- }
-
- string(const string& s)
- {
- _str = new char[s.size() + 1];
- strcpy(_str, s.c_str());
- _str[s.size()] = '\0';
- _capacity = s.size();
- _size = s.size();
- }
-
- string& operator=(const string& s)
- {
- for (int i = 0; i < size(); i++)
- {
- _str += s[i];
- }
- return *this;
- }
-
- ~string()
- {
- delete[] _str;
- _size = 0;
- _capacity = 0;
- }
-
-
-
- //
-
- // iterator
-
- iterator begin()
- {
- return _str;
- }
-
- iterator end()
- {
- return _str + _size;
- }
-
-
-
- // /
-
- // // modify
-
- void push_back(char c)
- {
- *this += c;
- }
-
- string& operator+=(char c)
- {
- if (_size == _capacity)
- {
- _capacity = _capacity == 0 ? 4 : 2 * _capacity;
- char* tmp = new char[_capacity +1];
- strcpy(tmp, _str);
- delete[] _str;
- _str = tmp;
- }
-
- _str[_size] = c;
- _str[_size + 1] = '\0';
- _size++;
-
- return *this;
- }
-
- void append(const char* str)
- {
- int i = 0;
- while (str[i])
- {
- push_back(str[i]);
- i++;
- }
- }
-
- string& operator+=(const char* str)
- {
- append(str);
- return *this;
- }
-
- void clear()
- {
- _size = 0;
- _str[0] = '\0';
- }
-
- void swap(string& s)
- {
- std::swap(_str,s._str);
- std::swap(_size, s._size);
- std::swap(_capacity, s._capacity);
- }
-
- const char* c_str()const
- {
- return _str;
- }
-
-
-
- ///
-
- capacity
-
- size_t size()const
- {
- return _size;
- }
-
- size_t capacity()const
- {
- return _capacity;
- }
-
- bool empty()const
- {
- return _str[0] == '\0';
- }
-
- void resize(size_t n, char c = '\0')
- {
- if (n > _capacity)
- {
- reserve(n);
- for (int i = _size; i < _capacity; i++)
- {
- _str[i] = c;
- }
- _size = _capacity;
- }
- else
- {
- _size = n;
- }
- }
-
- void reserve(size_t n)
- {
- if (n > _capacity)
- {
- _capacity = n;
- char* tmp = new char[_capacity + 1];
- strcpy(tmp, _str);
- delete[] _str;
- _str = tmp;
- }
- }
-
-
-
- ///
-
- access
-
- char& operator[](size_t index)
- {
- return _str[index];
- }
-
- const char& operator[](size_t index)const
- {
- return _str[index];
- }
-
-
-
- ///
-
- relational operators
-
- bool operator==(const string& s)
- {
- if (_size != s.size())
- return false;
- for (int i = 0; i < _size; i++)
- {
- if (_str[i] != s[i])
- return false;
- }
- return true;
- }
-
- bool operator!=(const string& s)
- {
- return !operator==(s);
- }
-
-
-
- 返回c在string中第一次出现的位置
-
- size_t find(char c, size_t pos = 0) const
- {
- for (size_t i = pos; i < _size; i++)
- {
- if (_str[i] == c)
- return i;
- }
- return std::string::npos;
- }
-
- 返回子串s在string中第一次出现的位置
-
- size_t find(const char* s, size_t pos = 0) const
- {
- const char* ptr = std::strstr(_str + pos, s);
-
- if (ptr == nullptr)
- return std::string::npos;
- else
- {
- return ptr - _str;
- }
- }
-
- 在pos位置上插入字符c/字符串str,并返回该字符的位置
-
- string& insert(size_t pos, char c)
- {
- if (_size == _capacity)
- {
- reserve(_capacity == 0 ? 4 : 2 * _capacity);
- }
- size_t end = _size - 1;
- while (end >= pos)
- {
- _str[end + 1] = _str[end];
- end--;
- }
- _str[pos] = c;
- return *this;
- }
-
- string& insert(size_t pos, const char* str)
- {
- int len = 0;
- while (str[len++]);
- if (_size + len > _capacity)
- {
- reserve(_size + len);
- }
-
- memmove(_str + pos + len, _str + pos, len * sizeof(char));
-
- for (int i = pos; i < pos + len; i++)
- {
- _str[i] = str[i - pos];
- }
- _size += len;
- return *this;
- }
-
-
-
- 删除pos位置上的元素,并返回该元素的下一个位置
-
- string& erase(size_t pos, size_t len)
- {
- memmove(_str + pos, _str + pos + len, (_size - pos-len) * sizeof(char));
- _size -= len;
- return *this;
- }
-
-
-
- };
-
- std::ostream& operator<<(std::ostream& _cout, const string& s)
- {
- for (int i = 0; i < s.size(); i++)
- {
- _cout << s[i];
- }
- return _cout;
- }
-
- std::istream& operator>>(std::istream& _cin, string& s)
- {
- char buffer[128];
- int len = 0;
- char bu = _cin.get();
- while (bu != ' ' && bu != '\n')
- {
- buffer[len] = bu;
- len++;
- bu = _cin.get();
- }
-
- for (int i = 0; i < len; i++)
- {
- s += buffer[i];
- }
-
- return _cin;
- }
-
- }