一、string类声明给大家推荐一个超级好用的刷面试题神器:牛客网,里面涵盖了各个领域的面试题库,还有大厂真题哦!
各种语言的编程题都有,并且很多公司都用这个网站来笔试,赶紧来刷题吧!!!
namespace yyh
{
class string
{
public:
string(const char* str = "");// 构造
~string();// 析构
string(const string& s);// 拷贝构造
string& operator=(const string& s);// 赋值拷贝
char* c_str() const;// 返回字符串
size_t size() const;// 返回size
char& operator[](size_t pos);// []访问
const char& operator[](size_t pos) const;// const[]访问
typedef char* iterator;// 迭代器
iterator begin();
iterator end();
typedef const char* const_iterator;// const迭代器
const_iterator begin() const;
const_iterator end() const;
void push_back(const char ch);// 尾插字符
void append(const char* str);// 尾插字符串
string& operator+=(const char ch);// +=重载
string& operator+=(const char* str);
void resize(size_t n, char ch = ')';// 初始化扩容find
size_t (constchar ) ch;// 查找字符find
size_t (constchar *, str= size_t pos 0 );// 查找字符串&
stringinsert (,size_t posconst char ) ch;// 插入字符&
stringinsert (,size_t posconst char *) str;// 插入字符串&
stringerase (,size_t pos= size_t len ) npos;// 删除private
:char
*; _str;
size_t _size;
size_t _capacity// _capacity表示有效字符个数public
:static
const = size_t npos - 1;}
;}
&
ostreamoperator <<(&ostream, out:: yyh&string) s;// 输出&
istreamoperator (>>&istream, in:: yyh&string) s;// 输入::
二、string类接口实现
2.1 构造函数
yyh::stringstring(constchar *) str:
_size (strlen()str),
_capacity ()_size=
{
_str new char [+_capacity 1 ];// _capacity表示有效字符个数strcpy
(,_str) str;}
_capacity
我们用::
表示有效字符的个数,那么开空间的时候就要多开一个位置(放string)
yyh::~string()delete[
{
];=_strnullptr
_str ; ==
_size 0 _capacity ; }::
::
2.3 拷贝构造
yyhstringstring(const&) string: s_size
( strlen(.)s)_str,_capacity
( .)s=_sizenew
{
_str char [ +1_capacity ] ;strcpy(
,._str) s;_str}::
::
2.3.1 现代写法
yyhstringstring(const&) string: s_str
( nullptr)::tmp
{
yyh(string .)s;_str// 构造swap(
,._str) tmp;_strswap(
,._size) tmp;_sizeswap(
,._capacity) tmp;_capacity}s._str
_str
先用s(s1)
构造一个tmp,交换tmp和s的::,因为tmp的生命周期只在当前栈帧,栈帧销毁自动调用析构函数。
这里要注意一定要先把_str置为空,因为&s的_str指向随机空间,交换给tmp后,调用析构函数就会程序崩溃。
yyh::string:: yyhoperatorstring=(const&) stringif s(
{
this !=& ) // 自己拷贝自己schar*
{
=new tmp char [ strlen(.)s+_str1 ] ;strcpy(
,.tmp) s;_strdelete[
];=_str;
_str = tmp.
_size ; s=_size.
_capacity ; s}_capacityreturn
*
this ;}::
&
2.4.1 现代写法
yyh::string:: yyhoperatorstring=(const&) stringif s(
{
this !=& ) =snullptr
{
_str ; ::tmp
yyh(string );sswap(
.,tmp)_str; _strswap(
.,tmp)_capacity; _capacityswap(
.,tmp)_size; _size}return
*
this ;}::
&
2.4.2 更简洁写法
yyh::string:: yyhoperatorstring=()swapstring s(
{
.,s)_str; _strswap(
.,s)_size; _sizeswap(
.,s)_capacity; _capacityreturn*
this ;}char
*
注意写这种写法的时候要有拷贝构造函数,s是拷贝构造出来的,生命周期只存在当前栈帧,出栈帧自动销毁。
2.5 返回字符串:::: yyhc_strstring()constreturn ;
{
} _str::
::
2.6 返回size
size_t yyhsizestring()constreturn ;
{
} _sizechar
&
2.7 []访问 & const[]访问
:::: yyhoperatorstring[]()assertsize_t pos(
{
<)pos ; _sizereturn[
] _str;pos}const
char
& :::: yyhoperatorstring[]()constsize_t posreturn [
{
] _str;pos}::
::
2.8 迭代器和const迭代器
yyh::string::iterator yyhbeginstring()return;
{
} _str::
::
yyh::string::iterator yyhendstring()return+
{
; _str } _size::
::
yyh::string::const_iterator yyhbeginstring()constreturn ;
{
} _str::
::
yyh::string::const_iterator yyhendstring()constreturn +
{
; _str } _sizeiterator
const_iterator
这里要注意void和::都是typedef出来的。
2.9 尾插字符:: yyhpush_backstring(constchar) if ch(
{
== )_size //扩容 _capacityif
{
(
== 0_capacity ) =4
{
_capacity ; }*=
2
_capacity ; char*
=new tmp char [ +1_capacity ] ;strcpy(
,)tmp; _strdelete[
];=_str;
_str } tmp[
]
_str=_size; [ ch+
_str1_size ] =';' ++ ;}
_sizevoid::
::
这里要注意的是:
2.10 尾插字符串1️⃣ 扩容时_capacity是否为0?
2️⃣ 结尾补充’\0’
append yyh(stringconstchar*) =strlen str(
{
size_t sz ) ;ifstr(+
) //扩容_size if sz > _capacity(
{
==
0 )_capacity = 4;
{
_capacity } while(
<
+ )_capacity *= _size 2 sz;
{
_capacity } char*
=
newchar tmp [ + 1]_capacity ; strcpy(,
);tmpdelete _str[]
;=;_str}
_str strcpy tmp(
+
,)_str ; _size+= str;}
_size :: sz&
::
尾插字符串首先要算出字符串的长度再看扩容多少。
2.11 +=重载yyh::stringoperator yyh+=string(constchar)push_back ( ch)
{
;// 复用chreturn*this
; }::&
::
yyh::stringoperator yyh+=string(constchar*) append( str)
{
;// 复用strreturn*this
; }void::
::
2.12 初始化扩容
resize yyh(string,char)size_t nif ( ch<
{
) [n ] _size=
{
_str';'n= ; }if
_size ( n)
if
( )n > _size//扩容
{
if (n > _capacity==
{
0
) =_capacity 4 ;}
{
_capacity while (<=
)
*= 2_capacity ; n}
{
_capacity char *=
new
char[ tmp + 1 ];_capacity strcpy (,)
;deletetmp[ _str];
=;}_strfor
_str ( tmpint
=
; <; i ++ _size) i [ n] i=;
{
_str}i= ; ch}
}
_size n < _size
n'n == _size
'
::
::
分情况讨论:
2.13 查找字符 & 字符串当find 时直接在n的位置补(
当const 时不用处理
当n > _size
时要先扩容再补充字符
size_t yyhcharstring)=0; while ch(
{
size_t i < )if
( [i ] _size==
{
) return_str;i} } chreturn
{
; i}
::
::
find npos(
const
size_t yyhcharstring*,)const char* str= size_t posstrstr
{
( +, p ) ;if_str ( pos== strnullptr)
// 没找到 returnp ; return(-
) npos;
} ::p & _str::::
insert
2.14 插入字符
yyh(string, yyhconststringchar)assertsize_t pos( <= ) ch;
{
if(pos + _size1)
//扩容 =_size + 1 > _capacity;
{
resize
size_t tmp ( _size ) ;}
=+tmp1;
while
size_t end ( _size ) []
= [end > pos-
{
_str1end] ; _str--end ; }[]
end=;
++
_str;posreturn * chthis
_size;}
_str[end + 1] = _str[end];
::&::
::
这里要注意while循环时,如果使用insert的形式就会出错,因为size_t是无符号数,恒大于0。
2.15 插入字符串yyh(string, yyhconststringchar*)size_t posassert ( <=) str;
{
=strlenpos ( _size);
size_t sz if (+str)// 扩容
= +_size ; sz > _capacityresize
{
(
size_t tmp ) _size ; sz/*if (_capacity == 0)
{
_capacity = 4;
}
while (_capacity < _size + sz)
{
_capacity *= 2;
}
char* tmp = new char[_capacity + 1];
strcpy(tmp, _str);
delete[]_str;
_str = tmp;*/
}=tmp+;
while
(
size_t end + _size ) sz[
] =end >= pos [ sz-
{
_str]end; -- _str;end } szfor(
end=;
<
; ++size_t i ) pos[ i ] sz= i*;
{
_str++i; } +=str;
strreturn*
this
_size ; sz}
end < pos + sz
::
&::
::
这里要注意在while循环时结束条件是:erase。
而且最后不能使用strcpy,会导致(也被拷贝
yyh,string) yyhassertstring(<)size_t pos; size_t lenif
{
(+pos ) _size=;
[ ]pos = len >= _size';'
{
_size } poselse
_strstrcpy_size( + ,+
+
)
{
;-=_str ; pos} _str return pos * lenthis;
_size } len'&'
operator
<< (&,
::
不能忘记补充&
2.17 输入<< 输出>> 重载ostream) for(autoostream: out) yyh// 不能用c_str()stringout s<<
{
; }return e ; s}&
{
operator ( e&
,
:: out&
)
istreamchar =>>.istreamget in( yyh)string; swhile
{
( ch != in'\n'&&!=' ')
+= ;ch = . get ch ( );
{
s } chreturn
ch ; in}c_str()
_size
in
输出的时候不能使用,因为有可能输出的字符串比大。
纸上得来终觉浅,绝知此事要躬行。来刷题巩固吧
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)