模拟实现string(v1)
Posted yumoz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模拟实现string(v1)相关的知识,希望对你有一定的参考价值。
string的模拟实现
1 先来介绍一下string
概述:string是C++标准库里面的一个重要部分,其主要工作是用于字符串处理。
2 常见用法
2.1 成员函数
3 模拟实现
class类的定义:
class string
public:
//具体函数实现,见下面部分给出
static const size_t npos;//类外定义
private:
char* _str;
size_t _size;
size_t _capacity;//存储有效字符
;
const size_t string::npos = -1;
3.1 基础接口实现
构造函数+拷贝构造函数+析构函数+赋值构造函数:
// 基础接口
//构造函数
string(const char* str = "")
_size = strlen(str);
_capacity = _size;
_str = new char[_capacity + 1];
strcpy(_str, str);
//现代写法的swap成员函数 简化程序代码
void swap(string& s)
/*std::swap(_str, s._str);
std::swap(_size, s._size);
std::swap(_capacity, s._capacity);*/
//域作用限定符,全局域
::swap(_str, s._str);
::swap(_size, s._size);
::swap(_capacity, s._capacity);
//s2(s1)拷贝构造
string(const string &s)
:_str(nullptr)
, _capacity(0)
, _size(0)
string temp(s._str);
// 多个交换
/*swap(_str, temp._str);
swap(_size, temp._size);
swap(_capacity, temp._capacity);*/
// 隐含 this->swap(temp);
swap(temp);//就近原则,使用的是局部的swap,当前类域找
string& operator=(string s)
/*swap(_str, s._str);
swap(_size, s._size);
swap(_capacity, s._capacity);*/
swap(s);
return *this;
//析构
~string()
delete[]_str;
_str = nullptr;
_size = _capacity = 0;
3.2 迭代器
// 迭代器
typedef char* iterator;
typedef const char* const_itertor;
iterator begin()
return _str;
iterator end()
return _str + _size; //end位置是\\0位置
const iterator begin() const
return _str;
const iterator end() const
return _str + _size;
3.3 operator[]实现
// &保证了 可读可写,出了作用域对象还在
char& operator[](size_t i)
assert(i < _size);//防止越界
return _str[i];
//只能读
const char& operator[](size_t i) const
assert(i < _size);
return _str[i];
3.4 容量部分实现
此部分主要实现的是size,capacity,判断是否为空,reserve,resize接口。
这里主要分析reserve接口和resize接口:
// capacity
size_t size()
return _size;
size_t size() const
return _size;
size_t capacity()const
return _capacity;
bool empty()const
return _size == 0;
//开空间 改变容量
void reserve(size_t n)
if (n > _capacity)
char* temp = new char[n + 1];
//strcpy(temp, _str);
strncpy(temp, _str,_size+1);
delete[]_str;
_str = temp;
_capacity = n;
//开空间,初始化,缩小,size也变换
void resize(size_t n, char ch = '\\0')
//空间足
if (n < _size)
//缩小,插入\\0,迫使其在n的位置终止
_str[n] = '\\0';
_size = n;
else
//容量不够,扩容
if (n > _capacity)
reserve(n);
// n<capacity
for (size_t i = _size; i < n; ++i)
_str[i] = ch;//插入字符
_str[n] = '\\0';//末尾为结束标志
_size = n;//记录容量
3.5 扩容(insert、push_back、append、+=)
首先分析如何insert一个字符:
其次,再次分析如何insert一个字符串:
string& insert(size_t pos, char ch)
assert(pos <= _size);
//容量已满
if (_size == _capacity)
size_t newcapacity = _capacity == 0 ? 16 : _capacity * 2;
reserve(newcapacity);//扩容
//移动pos位置及之后字符
//写法一 不推荐
/* int end = _size;
while (end >= (int)pos) // 避免0 - 1加(int)
_str[end+1] = _str[end];
--end;
_str[pos] = ch;
_size++;
return *this;
*/
//写法二 推荐
int end = _size + 1;
while (end > pos)
_str[end] = _str[end - 1];
--end;
//写法3 someproblem
/*char* end = _str + _size;
while (end >= _str + pos)
*(end + 1) = *end;
--end;
*/
_str[pos] = ch;
_size++;
return *this;
//pos位置之前 insert 字符串
void 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 >= (int)(pos + len))
_str[end] = _str[end - len];
--end;
*/
//实现办法 二
/* cout << "size: " << _size << endl;
cout << "_str[4]: " << _str[4] << endl;
cout << "_str[8]: " << _str[8] << endl;*/
size_t end = _size + len + 1;
//cout << "end:" << end << endl;
while (end > pos + len)
_str[end - 1] = _str[end - len - 1];//先从结束\\0 开始向后移动
--end;
//cout << "end: "<< end << endl;
//指针办法解决
/*char*end = _str + _size;
while (end >= _str + pos)
*(end + len) = *end;
--end;
*/
strncpy(_str + pos, str, len);
_size += len;
//*****************************
//修改
void push_back(char ch)
//if (_size == _capacity)
//
// //扩容
// reserve(2 * _capacity);
//
//_str[_size] = ch;
//++_size;
//_str[_size] = '\\0';//保证字符串终止
insert(_size, ch);
void append(const char* str)
//size_t len = _size + strlen(str);
//if (len > _capacity)
//
// //扩容
// reserve(len);
//
//strcpy(_str + _size, str);
//_size = len;
insert(_size, str);
//this 指针处理
string& operator+=(char ch)
push_back(ch);
return *this;//深拷贝
//+= 字符串
string& operator+=(const char* str)
append(str);
return *this;//深拷贝
3.6 清理
void clear()
_size = 0;
_str[_size] = '\\0';
void erase(size_t pos, size_t len = npos)
assert(pos < _size);
//删完、删的len超过_size
if (len == npos || pos+len >= _size)
_str[pos] = '\\0';//直接设为字符串终止
_size = pos;//修改大小
else//删除一小段
strcpy(_str + pos, _str + pos + len);//字符串向前覆盖移动
_size -= len;
//找一个字符
size_t find(char ch, size_t pos = 0)
for (size_t i = pos; i < _size; ++i)
if (_str[i] == ch)
return i;
return npos;
//找一个字符串
size_t find(const char* sub, size_t pos = 0)
const char* ret = strstr(_str + pos, sub);
if (ret == nullptr)
return npos;
else
return ret - _str;
3.7 关系运算
类内实现:
// 类内实现关系运算
//relational operators
bool operator<(const string& s)const
int res = strcmp(_str, s._str);
if (res < 0)
return true;
return false;
bool operator<=(const string& s)const
return !(*this > s);
bool operator>(const string& s)const
int res = strcmp(_str, s._str);
if (res > 0)
return true;
return false;
bool operator>=(const string& s)const
return !(*this < s);
bool operator==(const string& s)const
int res = strcmp(_str, s._str);
if (res == 0)
return true;
return false;
bool operator!=(const string& s)const
return !(*this == s);
类外实现:
实现办法一:利用strcmp函数实现
bool operator ==(const string&s1, string &s2)
return strcmp(s1.c_str(), s2.c_str()) == 0;
bool operator !=(const string&s1, string &s2)
return !(s1 == s2);
bool operator <(const string&s1, string &s2)
return strcmp(s1.c_str(), s2.c_str()) < 0;
bool operator <=(const string&s1, string &s2)
return s1<s2 || s1 == s2;
bool operator >(const string&s1, string &s2)
return !(s1 <= s2);
bool operator >=(const string&s1, string &s2)
return !(s1 < s2);
实现办法二:自己模拟实现比大小
bool operator>(const string&s1, const string&s2)
size_t i1 = 0, i2 = 0;
while (i1 < s1.size() && i2 < s2.size())
if (s1[i1] > s2[i2])
return true;
else if (s1[i1] < s2[i2])
return false;
else
++i1;
++i2;
if (i1 < s1.size())
return true;
else if (i2<s2.size())
return false;
else
return false;
bool operator==(const string& s1, const string& s2)
size_t i1 = 0, i2 = 0;
while (i1 < s1.size() && i2 < s2.size())
if (s1[i1] > s2[i2])
return false;
else if (s1[i1] < s2[i2])
return false;
else
++i1;
++i2;
if (i1 == s1.size() && i2 == s2.size())
return true;
else
return false;
3.8 流运算(>>,<<,getline)
ostream& operator<<(ostream& out, const string& s)
//方法一 :范围for解决
for (auto ch : s)
out << ch;
//方法二
/*for (size_t i = 0; i < s.size(); ++i)
out << s[i];
*/
return out;
istream& operator>>(istream& in, string&s)
s.clear();
//s.resize(0);//清理 == clear
char ch;
ch = in.get();
while (ch != ' ' && ch != '\\n')
s += ch;
//in>>ch;
in.get(ch); //获取
return in;
//Getline 操作
istream& getline(istream& in, string& s)
s.clear();
//s.resize(0);//清理 == clear
char ch;
ch = in.get();
while (ch != '\\n')
s += ch;
//in>>ch;
in.get(ch); //获取
return in;
4 总结
整体实 以上是关于模拟实现string(v1)的主要内容,如果未能解决你的问题,请参考以下文章