赞
踩
在c++的标准库中我们处理字符串的时候需要使用string类,库中的使用接口都非常方便。


为了让我们更加了解有关库中的相关函数,我们需要自己来实现一遍。
-
- string(const char* str = "")//构造函数
- {
- _size = strlen(str);
- _capacity = _size;
- _str = new char[_capacity + 1];
- memcpy(_str, str, _size + 1);
- }
-
- ~string()//析构函数
- {
- delete[] _str;
- _str = nullptr;
- _capacity = _size = 0;
- }
-

在这里我们需要注意的是我们要使用c语言中的memcpy函数,因为在string类中的字符串是包含'\0'这样的字符的,而在c语言中,规则就是遇到\0就会停止,所以需要以string类中的size为准。
- char& operator[](size_t pos)
- {
- assert(pos < _size);
- return _str[pos];
- }
-
- const char& operator[](size_t pos) const
- {
- assert(pos < _size);
- return _str[pos];
- }
- string& operator+=(char ch)
- {
- push_back(ch);
- return *this;
- }
-
- string& operator+=(const char* str)
- {
- append(str);
- return *this;
- }
-

这里实现的是字符串的下标取值和字符串的添加,在字符串的函数添加中我们复用了push_back和append函数。
具体实现如下:
- 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 (len + _size > _capacity)
- reserve((len + _size) + 2);
- memcpy(_str + _size, str,len+1);
- _size += len;
- }

不管是尾插函数的实现还是扩展字符串的函数实现,我们都需要给字符串在必要的时候扩容,而这里在c++的标准库中提供一个叫reserve的函数,那我们就可以来实现一下。
- void reserve(size_t n)
- {
-
- if (n > _capacity)
- {
- char* tmp = new char[n];
- memcpy(tmp, _str,n);
- delete[] _str;
- _str = tmp;
- _capacity = n;
- }
- }
这个函数就是在堆上开辟空间的,申请过后给一个临时指针,临时指针给str。
- typedef char* iterator;
- typedef const char* const_iterator;
-
- iterator end()
- {
- return _str + _size;
- }
-
- iterator begin()
- {
- return _str;
- }
-
- const_iterator end() const
- {
- return _str + _size;
- }
-
- const_iterator begin() const
- {
- return _str;
- }

string的迭代器就是指针的变型,所以当我们使用范围for也是可以的。
- ostream& operator<< (ostream& out, const string& s)//无法改变的字符串,所以需要加const
- {
- for (auto ch : s)
- {
- out << ch;
- }
-
- return out;
- }
-
- istream& operator >>(istream& in, string& s)//输入的字符
- {
- s.clear();
- char ch = in.get();
- //消除字符缓存区的字符
- while (ch == ' ' || ch == '\n')
- {
- ch = in.get();
- }
- char buff[128];
- size_t i = 0;
- while (ch != ' ' && ch != '\n')
- {
- buff[i++] = ch;
- if (i == 127)
- {
- buff[i] = '\0';
- s += buff;
- i = 0;
-
- }
- ch = in.get();
- }
-
- if (i != 0)
- {
- buff[i] = '\0';
- s += buff;
- }
-
- return in;

在之前的流提取的函数中,我们使用这个buff数组可以减少扩容的次数,是一种比较好的优化方案,只要buff数组被填满之后,我们就需要给重新置空,不会多次扩容。
- void erase(size_t pos, size_t len = npos)
- {
- assert(pos <= _size);
- if (len == npos || len + pos >= _size)
- {
- _str[pos] = '\0';
- _size = pos;
- _str[_size] = '\0';
- }
- else
- {
- size_t end = len + pos;
- while (end <= _size)
- {
- _str[pos++] = _str[end++];
- }
- _size -= len;
-
- }
-
- }
-
-
- size_t find(char ch, size_t pos = npos)
- {
- assert(pos <= _size);
- for (size_t i = pos; i < _size; i++)
- {
- if (ch == _str[i])
- return i;
- }
- return npos;
-
- }
-
- size_t find(const char* str, size_t pos = 0)
- {
- assert(pos < _size);
- const char* ptr = strstr(_str + pos, str);
- if (ptr)
- {
- return ptr - _str;
- }
- else
- return npos;
-
- }
-
- string substr(size_t pos = 0, size_t len = npos)
- {
- assert(pos < _size);
-
- size_t n = len;
- if (len == npos || pos + len > _size)
- {
- n = _size - pos;
- }
-
- string tmp;
- tmp.reserve(n + 2);
- for (size_t i = pos; i < pos + n; i++)
- {
- tmp += _str[i];
- }
-
- return tmp;
- }
- void insert(size_t pos, size_t n, char ch)
- {
- assert(pos < _size);
- if (n + _size >= _capacity)
- reserve(n + _size + 2);
- int end = _size;
- //挪动数据
- while ((int)pos <= end)//当end减小到最小时会转换成很大的数,这里会隐式转换。//while(pos<=end&&end!=npos)
- {
- _str[end + n] = _str[end];
- end--;
- }
- for (size_t i = 0; i < n; i++)
- {
- _str[pos + i] = ch;
- }
- _size += n;
- }
-
- void insert(size_t pos, const char* str)
- {
- assert(pos < _size);
- size_t len = strlen(str);
- size_t end = _size;
- if (len + _size > _capacity)
- {
- reserve(len + _size + 2);
- }
- while (pos <= end && end != npos)
- {
- _str[end + len] = _str[end];
- end--;
- }
- for (size_t i = 0; i < len; i++)
- {
- _str[pos + i] = str[i];
-
- }
- _size += len;
- }

这里就是简单的函数实现的数据插入和查找,唯一需要注意的是insert的size_t和int的强转。
这一系列的函数其实只需要写几个函数,其余的只需要逻辑的互斥性就可以实现,非常容易。
- bool operator < (const string & s) const
- {
- int ret = memcmp(_str, s._str, _size < s._size ? _size : s._size);//这里比较字符串的大小,将小的字符串长度来进行比较
-
- return ret == 0 ? _size < s._size : ret < 0;//如果比较的长度一样长,注意三种情况
- //"world"
- //"world" false
-
- //"world"
- //"worldxxx" true
-
- //"worldxxx"
- //"world" false 只有一种情况为真,_size<s._size
-
-
- }
-
- bool operator ==(const string& s) const
- {
- return _size == s._size &&
- memcmp(_str, s._str, s._size) == 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);
- }

- #pragma once
- #include<iostream>
- #include<assert.h>
- using namespace std;
- namespace mystring
- {
- class string
- {
- public:
- /*string(const char* str="")
- :_size(strlen(str))
- ;_capacity(_size)
- ;_str(new char[_capacity + 1])
- {
- strcpy(_str, str);
- }*/
-
-
-
- string(const char* str = "")//构造函数
- {
- _size = strlen(str);
- _capacity = _size;
- _str = new char[_capacity + 1];
- memcpy(_str, str, _size + 1);
- }
-
- string(const string& str) //拷贝构造函数
- {
- _str = new char[str._capacity + 1];
- //strcpy(_str, str._str);
- memcpy(_str, str._str, str._size + 1);
- _size = str._size;
- _capacity = str._capacity;
- }
-
- void swap(string &s)
- {
- std::swap(_size, s._size);
- std::swap(_capacity, s._capacity);
- std::swap(_str, s._str);
- }
-
- string& operator =( string tmp)
- {
- swap(tmp);
- return *this;
- }
-
- ~string()//析构函数
- {
- delete[] _str;
- _str = nullptr;
- _capacity = _size = 0;
- }
-
- const char* c_str()const
- {
- return _str;
- }
-
- size_t size() const
- {
- return _size;
- }
-
- char& operator[](size_t pos)
- {
- assert(pos < _size);
- return _str[pos];
- }
-
- const char& operator[](size_t pos) const
- {
- assert(pos < _size);
- return _str[pos];
- }
-
- void reserve(size_t n)
- {
-
- if (n > _capacity)
- {
- char* tmp = new char[n];
- memcpy(tmp, _str,n);
- delete[] _str;
- _str = tmp;
- _capacity = 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 (len + _size > _capacity)
- reserve((len + _size) + 2);
- memcpy(_str + _size, str,len+1);
- _size += len;
- }
-
- string& operator+=(char ch)
- {
- push_back(ch);
- return *this;
- }
-
- string& operator+=(const char* str)
- {
- append(str);
- return *this;
- }
-
- void insert(size_t pos, size_t n, char ch)
- {
- assert(pos < _size);
- if (n + _size >= _capacity)
- reserve(n + _size + 2);
- int end = _size;
- //挪动数据
- while ((int)pos <= end)//当end减小到最小时会转换成很大的数,这里会隐式转换。//while(pos<=end&&end!=npos)
- {
- _str[end + n] = _str[end];
- end--;
- }
- for (size_t i = 0; i < n; i++)
- {
- _str[pos + i] = ch;
- }
- _size += n;
- }
-
- void insert(size_t pos, const char* str)
- {
- assert(pos < _size);
- size_t len = strlen(str);
- size_t end = _size;
- if (len + _size > _capacity)
- {
- reserve(len + _size + 2);
- }
- while (pos <= end && end != npos)
- {
- _str[end + len] = _str[end];
- end--;
- }
- for (size_t i = 0; i < len; i++)
- {
- _str[pos + i] = str[i];
-
- }
- _size += len;
- }
-
- typedef char* iterator;
- typedef const char* const_iterator;
-
- iterator end()
- {
- return _str + _size;
- }
-
- iterator begin()
- {
- return _str;
- }
-
- const_iterator end() const
- {
- return _str + _size;
- }
-
- const_iterator begin() const
- {
- return _str;
- }
-
-
- void erase(size_t pos, size_t len = npos)
- {
- assert(pos <= _size);
- if (len == npos || len + pos >= _size)
- {
- _str[pos] = '\0';
- _size = pos;
- _str[_size] = '\0';
- }
- else
- {
- size_t end = len + pos;
- while (end <= _size)
- {
- _str[pos++] = _str[end++];
- }
- _size -= len;
-
- }
-
- }
-
-
- size_t find(char ch, size_t pos = npos)
- {
- assert(pos <= _size);
- for (size_t i = pos; i < _size; i++)
- {
- if (ch == _str[i])
- return i;
- }
- return npos;
-
- }
-
- size_t find(const char* str, size_t pos = 0)
- {
- assert(pos < _size);
- const char* ptr = strstr(_str + pos, str);
- if (ptr)
- {
- return ptr - _str;
- }
- else
- return npos;
-
- }
-
- /*string substr(size_t pos=0, size_t len=npos)
- {
- assert(pos <= _size);
- size_t n=len;
- if (len == npos || pos + len >= _size)
- {
- n = _size - pos;
- }
- string tmp;
- reserve(n);
- for (int i = 0; i < n; i++)
- {
- tmp += _str[pos + i];
- }
- return tmp;
- }*/
-
- string substr(size_t pos = 0, size_t len = npos)
- {
- assert(pos < _size);
-
- size_t n = len;
- if (len == npos || pos + len > _size)
- {
- n = _size - pos;
- }
-
- string tmp;
- tmp.reserve(n + 2);
- for (size_t i = pos; i < pos + n; i++)
- {
- tmp += _str[i];
- }
-
- return tmp;
- }
-
- void clear()
- {
- _str[_size] = '\0';
- _size = 0;
- }
-
- bool operator < (const string & s) const
- {
- int ret = memcmp(_str, s._str, _size < s._size ? _size : s._size);//这里比较字符串的大小,将小的字符串长度来进行比较
-
- return ret == 0 ? _size < s._size : ret < 0;//如果比较的长度一样长,注意三种情况
- //"world"
- //"world" false
-
- //"world"
- //"worldxxx" true
-
- //"worldxxx"
- //"world" false 只有一种情况为真,_size<s._size
-
-
- }
-
- bool operator ==(const string& s) const
- {
- return _size == s._size &&
- memcmp(_str, s._str, s._size) == 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);
- }
-
-
- static const size_t npos;
-
-
-
- private:
- size_t _size;
- size_t _capacity;
- char* _str;
- };
-
- const size_t string::npos = -1;
- //实现流的提取和插入
- ostream& operator<< (ostream& out, const string& s)//无法改变的字符串,所以需要加const
- {
- for (auto ch : s)
- {
- out << ch;
- }
-
- return out;
- }
-
- istream& operator >>(istream& in, string& s)//输入的字符
- {
- s.clear();
- char ch = in.get();
- //消除字符缓存区的字符
- while (ch == ' ' || ch == '\n')
- {
- ch = in.get();
- }
- char buff[128];
- size_t i = 0;
- while (ch != ' ' && ch != '\n')
- {
- buff[i++] = ch;
- if (i == 127)
- {
- buff[i] = '\0';
- s += buff;
- i = 0;
-
- }
- ch = in.get();
- }
-
- if (i != 0)
- {
- buff[i] = '\0';
- s += buff;
- }
-
- return in;
-
- }
-
-
- }
-
-

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。