您的位置:首页 > 其它

String深拷贝、比较及增删查改等操作

2016-03-20 21:04 351 查看
string类是c++默认提供的,但是了解string类的写法也是非常重要的,面试中有许多关于string类的题目,string类能够考察c++类和对象的掌握程度,一定程度上也考察了面试者的编程能力。 下面是string类的一些基本功能,由于面试的时间很短,在这极短的时间内全部实现string类的功能是不可能的,我们可以实现最基本的功能,类中的构造函数、析构函数、赋值,复制等功能。
#include<iostream>
using namespace std;
#include<assert.h>

class String
{
public:
//构造函数
String(char* str = "")//对于string s;用""表示空
:_str(new char[strlen(str) + 1])//+1,针对空字符串开辟空间
{
strcpy(_str, str);
_size = strlen(str);
_capacity = _size;
}
String(const String& s);
String& operator=(String& s);
~String();
void Display();
public:
//实现增删查改及比较大小
char& operator[](size_t index);//更改字符
bool operator==(const String& s);//比较两个字符串是否相等
int compare(const String& s);//比较字符串大小
void CheckCapacity(size_t size);//检查容量
void PushBack(char ch);//尾插字符
void PopBack();//尾删字符
void Insert(size_t pos, const char ch);//插入字符
void InsertS(size_t pos, const char* ch,size_t len);//插入字符串中len个字符
void Erase(size_t pos,size_t len);//删除pos后len个字符
int Find(const char ch);//查找字符,返回位置
int FindS(const char* ch);//查找字符串
private:
char* _str;
size_t _size;
size_t _capacity;
};
//深拷贝的现代写法
String::String(const String& s)
:_str(NULL)//防止释放有随机值的空间出错
{
char* tmp = s._str;
swap(_str, tmp);
_size = s._size;
_capacity = s._size;
}
String& String::operator = (String& s)
{
if (_str != s._str)
{
swap(_str, s._str);
}
return *this;
}
String::~String()//析构
{
if (_str)
{
delete[] _str;
_str = NULL;
_size = 0;
_capacity = 0;
}
}
char& String::operator[](size_t index)//更改字符
{
return _str[index];
}
bool String::operator==(const String& s)//比较两个字符串是否相等
{//重新定义char* cur和tmp,防止被改变,造成析构崩溃
char* cur = _str;
char* tmp = s._str;
while (cur && tmp)
{
if (*cur != *tmp)
{
return 0;
}
else
{
++cur;
++tmp;
if (*cur == NULL && *tmp == NULL)
return 1;
}
}
return 0;
}
int String::compare(const String& s)//比较字符串大小
{
char* cur = _str;
char* tmp = s._str;
while (cur && tmp)
{
if (*cur != *tmp)
{
return *cur - *tmp;
}
else
{
++cur;
++tmp;
if (*cur == NULL && *tmp == NULL)
return 0;
}
}
if (cur)
return *cur;
else
return -(*tmp);
}
void String::Display()
{
if (_size == 0)
cout << "NULL" ;
cout << _str << endl;
}
void String::CheckCapacity(size_t size)//检查容量
{
if (size+1 >= _capacity)//size+1考虑到'\0'占一个字节
{
_capacity = size > _capacity * 2 ? size : _capacity * 2;
_str = (char *)realloc(_str, sizeof(char)*_capacity);
}
}
void String::PushBack(char ch)//尾插字符
{
CheckCapacity(_size + 2);
_str[_size++] = ch;
_str[_size] = '\0';
}
void String::PopBack()//尾删
{
if (_size)
{
_str[_size - 1] = '\0';
--_size;
}
}
void String::Insert(size_t pos, const char ch)//插入字符
{
assert(pos);
CheckCapacity(_size + 1);
_size++;
int count = _size;
while (count != pos - 1)
{
_str[count] = _str[count - 1];
count--;
}
_str[pos-1]=ch;
}
void String::InsertS(size_t pos, const char* ch, size_t len)//插入字符串中len个字符
{
assert(pos);
CheckCapacity(_size + len);
_size = _size + len;
while (len)
{
Insert(pos,*ch);
pos++;
ch++;
len--;
}
}
void String::Erase(size_t pos, size_t len)//删除pos后len个字符
{
assert(pos);
assert(len);
while (_str[len + pos - 1])
{
_str[pos - 1] = _str[len + pos - 1];
_str[len + pos - 1] = NULL;//前移一位,删除一位
pos++;
}
_size -= len;
}
int String::Find(const char ch)//查找字符
{
int pos = 1;
char* str = _str;
while (str)
{
if (*str == ch)
{
return pos;
}
pos++;
str++;
}
return 0;
}
int String::FindS(const char* ch)//查找字符串,返回字符串的位置
{
char*  str= _str;
char* s2 = (char*)ch;
int pos = 1;
while (str)
{
char* s1 = str;
while (s1 && s2 && *s1==*s2)
{
s1++;
s2++;
}
if (*s2==NULL)//注意在进行一次字符串比较后,判断是否s2指向空
return pos;
str++;
pos++;
}
return 0;
}
测试用例如下:
void Test1()
{//拷贝构造、赋值、比较字符串大小
//String s;
//String s1("ssssss");
//String s2(s1);
//String s3 = s1;
//s.Display();
//s1.Display();
//s2.Display();
//s3.Display();
String S1("hello fo");
String S2("hello foc");
//String S2("hworld!");
//S1.Display();
//S1[6] = 't';
S1.Display();
bool b= S1 == S2 ;
cout << b << endl;
cout << S1.compare(S2) << endl;

}

void Test2()
{//字符串增删查找
String S1;
S1.PushBack('h');
S1.PushBack('e');
S1.PushBack('l');
S1.PushBack('l');
S1.PushBack('o');
S1.Display();

//S1.PopBack();
//S1.PopBack();
//S1.PopBack();
//S1.Display();
//S1.PopBack();
//S1.PopBack();
//S1.PopBack();
//S1.Display();
String S2("hello orld!");
//S2.Insert(7,'w');
//S2.Display();
//S2.InsertS(6, " to try!", 3);
//S2.Display();
//S2.Erase(6, 3);
//S2.Display();
//cout << "d->" << S2.Find('d') << endl;
cout << "ello->" << S2.FindS("ello ") << endl;
}
以上是本人对string类的部分实现,如有不足,请多指教。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  String 深拷贝