【C++】string的模拟实现

1. 什么是string

string是标准模板库(STL)中的一类用来管理字符串数据的数据结构。

string类文档说明

2. 模拟实现

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <assert.h>
#include <string>
#include <cstring>		

using namespace std;
namespace lzh {
	//string正向迭代器
	template<class TP>
	struct cPtr {
		cPtr(TP* ptr) :_ptr(ptr)
		{}
		cPtr(const cPtr<TP>& p) :_ptr(p._ptr)
		{}
		bool operator!=(const cPtr<TP>& p) const {
			return _ptr != p._ptr;
		}
		TP& operator*() const {
			return *_ptr;
		}
		cPtr<TP>& operator++() {
			++_ptr;
			return *this;
		}
		cPtr<TP> operator++(int) {
			cPtr<TP> tmp(*this);
			++_ptr;
			return tmp;
		}
	private:
		TP* _ptr;
	};
	//string反向迭代器
	template<class TP>
	struct rPtr {
		rPtr(TP* ptr) :_ptr(ptr)
		{}
		rPtr(const rPtr<TP>& p) :_ptr(p._ptr)
		{}
		bool operator!=(const rPtr<TP>& p) const {
			return _ptr != p._ptr;
		}
		TP& operator*() const {
			return _ptr[-1];
		}
		rPtr<TP>& operator++() {
			--_ptr;
			return *this;
		}
		rPtr<TP> operator++(int) {
			rPtr<TP> tmp(*this);
			--_ptr;
			return tmp;
		}
	private:
		TP* _ptr;
	};

	class string {
	public:
		typedef cPtr<char>       iterator;
		typedef cPtr<const char> const_iterator;
		typedef rPtr<char>       reverse_iterator;
		typedef rPtr<const char> const_reverse_iterator;
		//构造
		string(const char* str = "")
			:_size(strlen(str)), _capacity(_size + 1) {
			_str = new char[_capacity + 1];
			memcpy(_str, str, (_size + 1) * sizeof(char));
		}
		//拷贝构造
		string(const string& s)
			:_size(strlen(s._str)), _capacity(s._capacity) {
			_str = new char[_capacity + 1];
			memcpy(_str, s._str, (_size + 1) * sizeof(char));
		}
		//赋值重载
		//1.普通写法
		/*string& operator=(const string& s) {
			if (this != &s) {
				delete[] _str;
				_str = new char[s._capacity];
				memcpy(_str, s._str, s._capacity * sizeof(char));
				_size = s._size;
				_capacity = s._capacity;
			}
			return *this;
		}*/

		//2.牛b写法
		void swap(string& s) {
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}
		string& operator=(string s) {
			swap(s);
			return *this;
		}
		//析构
		~string() {
			delete[] _str;
			_str = nullptr;
		}

		iterator begin() {
			return cPtr<char>(_str);
		}

		iterator end() {
			return cPtr<char>(_str + _size);
		}

		const_iterator begin() const {
			return cPtr<const char>(_str);
		}

		const_iterator end() const {
			return cPtr<const char>(_str + _size);
		}

		reverse_iterator rbegin() {
			return rPtr<char>(_str + _size);
		}

		reverse_iterator rend() {
			return rPtr<char>(_str);
		}

		const_reverse_iterator rbegin() const {
			return rPtr<const char>(_str + _size);
		}

		const_reverse_iterator rend() const {
			return rPtr<const char>(_str);
		}

		// modify
		//扩容直接开新空间然后拷贝,释放旧的
		void reserve(size_t n) {
			if (n > _capacity) {
				char* temp = new char[n + 1];
				memcpy(temp, _str, (_size + 1) * sizeof(char));
				delete[] _str;
				_str = temp;

				_capacity = n;
			}
		}
		
		void push_back(const char c) {
			if (_size == _capacity) {
				reserve(_capacity * 2);
			}
			_str[_size++] = c;
			_str[_size] = 0;
		}

		string& operator+=(const char c) {
			push_back(c);
			return *this;
		}

		void append(const char* str) {
			size_t len = strlen(str);
			if (len + _size > _capacity) {
				reserve(len + _size);
			}
			memcpy(_str + _size, str, len * sizeof(char));
			_str[_size += len] = 0;
		}

		string& operator+=(const char* str) {
			append(str);
			return *this;
		}

		void clear() {
			_str[_size = 0] = 0;
		}

		const char* c_str() const {
			return _str;
		}

		// capacity
		size_t size() const {
			return _size;
		}

		size_t capacity() const {
			return _capacity;
		}

		bool empty() const {
			return _size == 0;
		}
		//n > size就依次插入
		//否则n位置直接设为0,size=n
		void resize(size_t n, const char c = '\0') {
			while (_size < n) {
				push_back(c);
			}
			_str[_size = n] = 0;
		}

		// access
		char& operator[](size_t index) {
			assert(index < _size);
			return _str[index];
		}

		const char& operator[](size_t index) const {
			assert(index < _size);
			return _str[index];
		}

		//relational operators
		bool operator<(const string& s) const {
			int ret = memcmp(_str, s._str, _size < s._size ? _size : s._size);
			return ret == 0 ? _size < s._size : ret < 0;
		}

		bool operator==(const string& s) const {
			return _size == s._size && 0 == memcmp(_str, s._str, _size < s._size ? _size : s._size);
		}

		bool operator<=(const string& s) const {
			return *this < s || *this == s;
		}

		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);
		}

		// 返回c在string中第一次出现的位置
		size_t find(char c, size_t pos = 0) const {
			assert(pos < _size);
			while (pos < _size) {
				if (_str[pos++] == c) {
					return pos;
				}
			}
			return npos;
		}

		// 返回子串s在string中第一次出现的位置
		size_t find(const char* s, size_t pos = 0) const {
			assert(pos < _size);
			const char* ptr = strstr(_str, s);
			if (nullptr == ptr) {
				return npos;
			}
			return ptr - _str;
		}

		// 在pos位置上插入字符c/字符串str,并返回该字符的位置
		size_t insert(size_t pos, size_t n, const char c) {
			if (_size + n > _capacity) {
				reserve(_size + n);
			}
			size_t end = _size + n;
			while (end > pos) {
				_str[end] = _str[end - n];
				--end;
			}
			for (size_t i = 0; i < n; ++i) {
				_str[i + pos] = c;
			}
			_str[_size += n] = 0;
			return pos;
		}
		size_t insert(size_t pos, const char* str) {
			size_t len = strlen(str);
			if (len + _size > _capacity) {
				reserve(len + _size);
			}
			size_t end = _size + len;
			while (end > pos) {
				_str[end] = _str[end - len];
				--end;
			}
			memcpy(_str + pos, str, len * sizeof(char));
			_str[_size += len] = 0;
			return pos;
		}

		// 删除pos位置上的元素,并返回该元素的下一个位置
		size_t erase(size_t pos, size_t len = npos) {
			if (len == npos || len + pos >= _size) {
				_str[_size = pos] = 0;
				return pos;
			}
			size_t end = pos + len;
			while (end < _size) {
				_str[end - len] = _str[end];
				++end;
			}
			_str[_size -= len] = 0;
			return pos;
		}

		string substr(size_t pos, size_t len = npos) {
			assert(pos < _size);
			string ret;
			if (len == npos || pos + len >= _size) {
				ret += _str + pos;
				return ret;
			}
			for (size_t i = 0; i < len; ++i) {
				ret += _str[i + pos];
			}
			return ret;
		}

		friend ostream& operator<<(ostream& _cout, const string& s);
		friend istream& operator>>(istream& _cin, string& s);

		static size_t npos;

	private:
		char* _str;
		size_t _size;
		size_t _capacity;
	};

	size_t string::npos = -1;

	ostream& operator<<(ostream& out, const string& s) {
		for (auto& c : s) {
			out << c;
		}
		out << endl;
		return out;
	}

	istream& operator>>(istream& in, string& s) {
		//由于cin和scanf类似
		//会把空格和换行认为是分割字符直接跳过
		//因此若想拿到空格或者换行符需要用到
		//对象in里的成员函数get()
		char ch = in.get();
		while (ch == ' ' || ch == '\n') {
			ch = in.get();
		}
		//每次应该清空字符串
		s.clear();
		char buffer[128] = { 0 };
		size_t i = 0;
		while (ch != ' ' && ch != '\n') {
			buffer[i++] = ch;
			if (i == 126) {
				buffer[i] = 0;
				s += buffer;
				i = 0;
			}
			ch = in.get();
		}
		if (i != 0) {
			buffer[i] = 10;
			s += buffer;
		}
		return in;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值