对于 string 类一定并不陌生,我们重点介绍一部分接口。
1. void resize(size_t n,char c); 将字符串大小改变,如果大小是增加则后面添加字符 c,减少则保留前 n 个字符。
2. void resize(size_t n); 和上面一样,只是默认添加字符为 '\0'。
3. void reserve(size_t n); 扩容。
4. size_t find(char c, size_t pos = 0) const; 返回从 pos 开始找到的第一个字符 c的位置。没有找到返回 npos, npos 为类的一个静态成员变量,定义为:static const size_t npos = -1。
5. size_t find(const char* s, size_t pos = 0) const; 返回从 pos 开始找到的第一个字符串 s 的起始位置。没有找到返回 npos。
6. string substr(size_t pos, size_t n); 截取string从pos位置开始的n个字符。
7. string& insert(size_t pos, char c); 在pos位置插入字符 c。
8. string& insert(size_t pos, const char* _str); 在pos位置插入字符串。
9. string& erase(size_t pos, size_t len); 删除从 pos开始往后的 len个字符。
10. void append(const char* _str); 在string后面连接一个字符串。
11. void append(size_t n, char c); 在string后面连接 n 个字符 c。
12. void clear(); 清空string。
该类中还有许多运算符重载函数和类中的默认成员函数等等,下面是模拟实现该类以及所有经常用到的接口:
#include<iostream>
#include<string.h>
#include<assert.h>
namespace smx
{
class string
{
private:
size_t capacity;
size_t size;
char *str;
static const size_t npos = -1;
private:
friend std::ostream& operator<<(std::ostream& _cout, const smx::string& s);
public:
typedef char* Iterator;
public:
string(const char *_str = "")
{
if (nullptr == _str)
{
return;
}
size = strlen(_str);
capacity = size;
str = new char[capacity + 1];
strcpy(str, _str);
}
string(const string& s) :str(new char[s.capacity + 1]), size(s.size), capacity(s.capacity)
{
strcpy(str, s.str);
}
string& operator=(const string& s)
{
if (this != &s)
{
char *pstr = new char[s.capacity + 1];
strcpy(pstr, s.str);
delete str;
str = pstr;
size = s.size;
capacity = s.capacity;
}
return *this;
}
~string()
{
if (str)
{
delete[] str;
str = nullptr;
}
}
Iterator begin()
{
return str;
}
Iterator end()
{
return str + size;
}
void push_back(char c)
{
if (size == capacity)
{
reserve(capacity * 2);
}
str[size++] = c;
str[size] = '\0';
}
void append(const char* _str)
{
for (size_t i = 0; i < strlen(_str); i++)
{
push_back(_str[i]);
}
}
void append(size_t n, char c)
{
for (size_t i = 0; i < n; i++)
{
push_back(c);
}
}
string& operator+=(const char c)
{
push_back(c);
return *this;
}
string& operator+=(const char* _str)
{
append(_str);
return *this;
}
bool operator<(const string& s)
{
return strcmp(str, s.str) < 0;
}
bool operator<=(const string& s)
{
return strcmp(str, s.str) <= 0;
}
bool operator>(const string& s)
{
return strcmp(str, s.str) > 0;
}
bool operator>=(const string& s)
{
return strcmp(str, s.str) >= 0;
}
bool operator==(const string& s)
{
return strcmp(str, s.str) == 0;
}
bool operator!=(const string& s)
{
return strcmp(str, s.str) != 0;
}
void clear()
{
size = 0;
str[size] = '\0';
}
const char* c_str() const
{
return str;
}
size_t Size() const
{
return size;
}
size_t Capacity() const
{
return capacity;
}
bool empty() const
{
return size == 0;
}
void resize(size_t n,char c)
{
if (n > size)
{
if (n > capacity)
{
reserve(n);
}
for (size_t i = size; i < n; i++)
{
str[i] = c;
}
}
str[n] = '\0';
size = n;
}
void resize(size_t n)
{
if (n > size)
{
if (n > capacity)
{
reserve(n);
}
memset(str + size, '\0', n - size);
}
size = n;
str[n] = '\0';
}
void reserve(size_t n)
{
if (n > capacity)
{
char *_str=new char[n + 1];
strcpy(_str, str);
delete str;
str = _str;
capacity = n;
}
}
const char& operator[](size_t index)
{
assert(index < size);
return str[index];
}
const char& operator[](size_t index) const
{
assert(index < size);
return str[index];
}
size_t find(char c, size_t pos = 0) const
{
assert(pos < size);
for (size_t i = pos; i < size; i++)
{
if (str[i] == c)
{
return i;
}
}
return npos;
}
size_t find(const char* s, size_t pos = 0) const
{
assert(pos < size);
if (strstr(str, s) == nullptr)
{
return npos;
}
char *_str = strstr(str, s);
for (size_t i = pos; i < size; i++)
{
if (&str[i] == _str)
{
return i;
}
}
return npos;
}
string substr(size_t pos, size_t n)
{
string s(str);
s.erase(0, pos);
s.erase(n, s.size - n);
return s;
}
string& insert(size_t pos, char c)
{
assert(pos<size);
if (size == capacity)
{
reserve(capacity * 2);
}
for (size_t i = size; i > pos; i--)
{
str[i] = str[i - 1];
}
str[pos] = c;
size++;
str[size] = '\0';
return *this;
}
string& insert(size_t pos, const char* _str)
{
assert(pos<size);
size_t len = strlen(_str);
if (len + size > capacity)
{
reserve(capacity * 2 + len);
}
for (size_t i = size + len; i > pos; i--)
{
str[i] = str[i - len];
}
for (size_t i = pos; i < pos + len; i++)
{
str[i] = _str[i - pos];
}
size += len;
str[size] = '\0';
return *this;
}
string& erase(size_t pos, size_t len)
{
assert(pos + len <= size);
for (size_t i = pos; i < size; i++)
{
str[i] = str[i + len];
}
size -= len;
str[size] = '\0';
return *this;
}
};
}
std::ostream& smx::operator<<(std::ostream& _cout, const smx::string& s)
{
std::cout << s.str;
return _cout;
}