string 用法
string
string 模拟
#pragma once
#include <assert.h>
#include <string.h>
#include "ReverseIterator.h"
namespace sjy
{
class string
{
public:
typedef char* iterator;
typedef const char* const_iterator;
typedef Reverse_iterator<iterator, char&, char*> reverse_iterator;
typedef Reverse_iterator<const_iterator, const char&, const char*> const_reverse_iterator;
iterator begin()
{
return _str;
}
iterator end()
{
return _str + _size;
}
const_iterator begin() const
{
return _str;
}
const_iterator end() const
{
return _str + _size;
}
reverse_iterator rbegin()
{
return reverse_iterator(end());
}
reverse_iterator rend()
{
return reverse_iterator(begin());
}
const_reverse_iterator rbegin() const
{
return const_reverse_iterator(end());
}
const_reverse_iterator rend() const
{
return const_reverse_iterator(begin());
}
string(const char* str = "")
{
size_t len = strlen(str);
_size = len;
_capacity = len;
_str = new char[_capacity + 1]{ 0 };
memcpy(_str, str, sizeof(char) * (_size + 1));
}
~string()
{
delete[] _str;
_str = nullptr;
_size = _capacity = 0;
}
string(const string& other)
{
_size = other._size;
_capacity = other._capacity;
_str = new char[_capacity + 1]{ 0 };
memcpy(_str, other._str, sizeof(char) * (_size + 1));
}
string& operator=(string other)
{
swap(other);
return *this;
}
size_t size() const
{
return _size;
}
size_t capacity() const
{
return _capacity;
}
void resize(size_t n, char c = '\0')
{
if (n < _size)
{
*(_str + n) = '\0';
_size = n;
}
else
{
reserve(n);
for (int i = _size; i < n; i++)
{
*(_str + i) = c;
}
*(_str + n) = '\0';
_size = n;
}
}
void reserve(size_t n = 0)
{
if (n > _capacity)
{
_capacity = n;
char* tmp = new char[_capacity + 1]{ 0 };
memcpy(tmp, _str, sizeof(char) * (_size + 1));
delete[] _str;
_str = tmp;
}
}
char& operator[](size_t pos)
{
assert(pos < _size);
return *(_str + pos);
}
const char& operator[](size_t pos) const
{
assert(pos < _size);
return *(_str + pos);
}
void push_back(char c)
{
if (_size == _capacity)
{
reserve(_capacity == 0 ? 4 : 2 * _capacity);
}
*(_str + _size) = c;
_size++;
*(_str + _size) = '\0';
}
void append(const char* str)
{
size_t len = strlen(str);
if (_size + len > _capacity)
{
reserve(_size + len);
}
for (int i = 0; i <= len; i++)
{
*(_str + _size + i) = *(str + i);
}
_size += len;
}
string& operator+=(char c)
{
push_back(c);
return *this;
}
string& operator+=(const char* str)
{
append(str);
return *this;
}
void insert(size_t pos, size_t n, char c)
{
assert(pos <= _size);
if (_size + n > _capacity)
{
reserve(_size + n);
}
for (int i = _size + n; i >= pos + n && i != npos; i--)
{
*(_str + i) = *(_str + i - n);
}
for (int i = 0; i < n; i++)
{
*(_str + pos + i) = c;
}
_size += n;
}
void insert(size_t pos, const char* str)
{
assert(pos <= _size);
size_t len = strlen(str);
if (_size + len > _capacity)
{
reserve(_size + len);
}
for (int i = _size + len; i >= pos + len && i != npos; i--)
{
*(_str + i) = *(_str + i - len);
}
for (int i = 0; i < len; i++)
{
*(_str + pos + i) = *(str + i);
}
_size += len;
}
string& erase(size_t pos = 0, size_t len = npos)
{
assert(pos <= _size);
if (len == npos || pos + len >= _size)
{
*(_str + pos) = '\0';
_size = pos;
}
else
{
for (int i = pos + len; i <= _size; i++)
{
*(_str + i - len) = *(_str + i);
}
_size -= len;
}
return *this;
}
size_t find(char c, size_t pos = 0) const
{
for (int i = pos; i < _size; i++)
{
if (*(_str + i) == c)
{
return i;
}
}
return npos;
}
size_t find(const char* str, size_t pos = 0) const
{
const char* ptr = strstr(_str + pos, str);
if (ptr == nullptr)
{
return npos;
}
else
{
return ptr - _str;
}
}
string substr(size_t pos = 0, size_t len = npos) const
{
assert(pos < _size);
if (len == npos || pos + len > _size)
{
len = _size - pos;
}
char* tmp = new char[len + 1]{ 0 };
for (int i = 0; i < len; i++)
{
*(tmp + i) = *(_str + pos + i);
}
string str(tmp);
delete[] tmp;
return str;
}
const char* c_str()
{
return _str;
}
void clear()
{
_size = 0;
*_str = '\0';
}
void swap(string& str)
{
std::swap(_str, str._str);
std::swap(_size, str._size);
std::swap(_capacity, str._capacity);
}
bool operator<(const string& str) const
{
int size1 = this->_size;
int size2 = str._size;
int minsize = size1 < size2 ? size1 : size2;
for (int i = 0; i < minsize; i++)
{
if (*(_str + i) > *(str._str + i))
{
return false;
}
else if (*(_str + i) < *(str._str + i))
{
return true;
}
}
if (size1 == size2 || size1 > size2)
{
return false;
}
else if (size1 < size2)
{
return true;
}
}
bool operator==(const string& str) const
{
if (_size == str._size && memcmp(_str, str._str, sizeof(char) * _size) == 0)
{
return true;
}
return false;
}
bool operator>(const string& str) const
{
return !((*this) < str || (*this) == str);
}
bool operator<=(const string& str) const
{
return ((*this) < str || (*this) == str);
}
bool operator>=(const string& str) const
{
return ((*this) > str || (*this) == str);
}
private:
char* _str;
size_t _size;
size_t _capacity;
static size_t npos;
};
size_t string::npos = -1;
std::istream& operator>>(std::istream& cin, string& str)
{
str.clear();
char c = cin.get();
while (c == ' ' || c == '\0')
{
c = cin.get();
}
char buff[128] = { 0 };
int i = 0;
while (c != ' ' && c != '\0')
{
buff[i++] = c;
if (i == 127)
{
str += buff;
i = 0;
}
c = cin.get();
}
if (i != 0)
{
*(buff + i) = '\0';
str += buff;
}
return cin;
}
std::ostream& operator<<(std::ostream& cout, const string& str)
{
for (auto c : str)
{
cout << c;
}
return cout;
}
}