string类的基本实现,包括增删查找,源代码如下
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
#include <assert.h>
using namespace std;
namespace STR
{
class String
{
public:
typedef char* iterator;
// iterator
iterator begin()
{
return _str;
}
iterator end()
{
return _str + _size;
}
//缺省的构造函数 -可用于无参或有参
//str被初始化为空字符串,空字符串是有效的字符串,它的长度为1,是一块合法的内存单元而不是NULL。
String(const char* str = "")
{
assert(str);
_size = strlen(str);
_capacity = _size; //能存放的容量,不计算\0
_str = new char[_capacity + 1];
strcpy(_str, str);
}
//String(const char* str = "")
// :_str(new char[strlen(str) + 1])
//{
// strcpy(_str, str);
//}
//析构函数
~String()
{
if (_str)
{
delete[]_str;
_str = nullptr;
_size = _capacity = 0;
}
}
//引用,s为别名
void Swap(String& s)
{
swap(this->_str, s._str);
swap(this->_size, s._size);
swap(this->_capacity, s._capacity);
}
//拷贝构造函数 copy(s1)
String(const String& s)
:_str(nullptr)
, _size(0)
, _capacity(0)
{
String tmp(s._str);
this->Swap(tmp);
}
赋值(1) s1 = s2
//String& operator = (const String &s)
//{
// String tmp(s._str);
// Swap(tmp);
//}
//赋值(2) s1 = s2 先用s2拷贝构造了一个s,把s的值与当前的s1交换
String& operator = (String s)
{
Swap(s);
return *this;
}
//strcmp()
bool operator<(const String& s) const
{
/*if (strcmp(_str, s._str) < 0)
return true;
else
return false;*/
//abcd abcd //false
//abcde abcd //false
//abcd abcde //true
size_t len1 = 0;
size_t len2 = 0;
while (len1 <= _size && len2 <= s._size)
{
if (_str[len1] < s._str[len2])
{
return true;
}
else if (_str[len1] == s._str[len2])
{
len1++;
len2++;
}
else
return false;
}
if (len2 < s._size)
{
return true;
}
else
{
return false;
}
}
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);
}
bool operator==(const String& s) const
{
if (strcmp(_str, s._str) == 0)
return true;
else
return false;
}
bool operator!=(const String& s) const
{
return !(*this == s);
}
void Reserve(size_t n)
{
//新传入的空间大小比原空间小,开辟新的空间,将原空间元素拷贝过去,释放旧空间
if (n > _capacity)
{
char* str = new char[n + 1];
strcpy(str, _str);
delete[] _str;
_str = str;
_capacity = n;
}
}
//后插 注:字符串末尾需加上\0
void PushBack(char ch)
{
if (_size == _capacity)
{
Reserve(_capacity + 2);
}
_str[_size] = ch;
++_size;
_str[_size] = '\0';
}
void Append(size_t n, char ch)
{
for (size_t i = 0; i < n; ++i)
PushBack(ch);
}
//后面加一个字符串 "hello" "xxxxxxxxxxxxxxxxxxxxxxxxxx"
void Append(const char* str)
{
int len = strlen(str); //要插入的字符串长度
while ((_size + len) > _capacity)
{
Reserve(_capacity + len);
}
strcpy(_str + _size, str);
_size += len;
_str[_size] = '\0';
}
String& operator+=(char ch)
{
PushBack(ch);
return *this; //为了支持链式访问
}
String& operator+=(const char* str)
{
Append(str);
return *this;
}
void Insert(size_t pos, char ch)
{
assert(pos <= _size);
if (_capacity == _size)
{
Reserve(_capacity + 2);
}
size_t end = _size;
while (end >= pos)
{
_str[end] = _str[end - 1];
end--;
}
_str[pos] = ch;
_size++;
_str[_size] = '\0';
}
void Insert(size_t pos, const char* str)
{
assert(pos <= _size);
size_t len = strlen(str);
while (_capacity < (_size + len))
{
Reserve(_capacity * 2);
}
size_t end = _size;
while (end >= pos)
{
_str[end + len] = _str[end];
end--;
}
while (*str)
{
_str[pos++] = *str++;
}
_size += len;
}
void Erase(size_t pos, size_t len)
{
assert(pos <= _size);
int end = pos + len;
while (end != _size)
{
_str[pos] = _str[end];
pos++;
end++;
}
_size -= len;
}
//pos为缺省值,若未给的话,默认从0开始
size_t Find(char ch, size_t pos = 0) const
{
assert(ch || pos);
size_t begin = pos;
while (begin <= _size)
{
if (_str[begin] == ch)
return begin+1;
begin++;
}
return pos;
}
size_t Find(const char* str, size_t npos = 0) const
{
assert(npos >= 0 && npos < _size);
size_t len = strlen(str); //要查找的字符串长度
for (size_t i = 0; i < _size - len; i++)
{
if (str[0] == _str[i])
{
char* tmp = new char[len + 1];
for (int j = 0; j < len; j++)
{
tmp[j] = _str[j + i];
}
tmp[len] = '\0';
if (strcmp(tmp, str) == 0)
return i;
}
}
return npos;
}
char* c_str()
{
return _str;
}
char& operator[](size_t pos)
{
assert(pos < _size);
return _str[pos];
}
size_t Size()
{
return _size;
}
size_t Capacity()
{
return _capacity;
}
private:
char* _str;
size_t _size;
size_t _capacity;
};
void test1()
{
String s1("hello");
String s2(s1);
String s3 = "world";
cout << s1.c_str() << endl;
cout << s2.c_str() << endl;
cout << s3.c_str() << endl;
cout << (s1 < s2) << endl; //0
cout << (s1 > s2) << endl; //0
cout << (s1 < s3) << endl; //1
cout << (s1 > s2) << endl; //0
cout << (s1 <= s2) << endl; //1
cout << (s1 == s2) << endl; //1
cout << (s1 <= s3) << endl; //1
cout << (s1 >= s2) << endl; //1
cout << (s1 != s2) << endl; //0
s1 += 'e';
cout << s1.c_str() << endl;
s1 += " world";
cout << s1.c_str() << endl;
}
void test2()
{
String s1("hello");
String s2 = "world";
cout << s1.c_str() << endl;
cout << s1.Capacity() << endl;
cout << s2.c_str() << endl;
s1.PushBack(' ');
cout << s1.c_str() << endl;
cout << s1.Capacity() << endl;
s1.Append("abcdefghijklmnopqrstuvwxy");
cout << s1.c_str() << endl;
cout << s1.Capacity() << endl;
s1.Insert(4, 'x');
cout << s1.c_str() << endl;
cout << s1.Capacity() << endl;
s1.Insert(5, "abcdef");
cout << s1.c_str() << endl;
cout << s1.Capacity() << endl;
s1.Erase(5, 6);
cout << s1.c_str() << endl;
cout << endl;
//找出ch第一次出现的位置,返回它的下标,找不到返回0
cout << "找出ch第一次出现的位置,返回它的下标,找不到返回0" << endl;
cout << s1.Find('h', 5) << endl;
cout << s1.Find('z', 0) << endl;
cout << endl;
cout << s1.Find("abcd", 0) << endl;
}
}