String的模拟实现

在这里插入图片描述

欢迎来到Cefler的博客
博客主页:那个传说中的man的主页
个人专栏:题目解析
推荐文章:题目大解析2


目录

  • 迭代器
  • 构造函数和析构函数
  • c_str
  • 返回大小和容量和扩容
  • 访问(operaotr[])
  • 尾插追加
  • insert
  • erase和clear
  • resize
  • find
  • substr
  • 运算符重载以及赋值
  • 流插入
  • 流提取
  • swap
  • 拷贝构造函数
  • string.h

迭代器

typedef char* iterator;
		typedef const char* const_iterator;//常量迭代器

		iterator begin()
		{
			return _str;
		 }
		iterator end()
		{
			return _str+_sz;
		}
		const_iterator begin()const
		{
			return _str;
		}
		const_iterator end()const
		{
			return _str + _sz;
		}

构造函数和析构函数

string(const char* str = "") //构造函数
			:_sz(strlen(str))
			, _capacity(_sz)
		{
			_str = new char[_capacity==0?4:_capacity+1];//防止_capacity为0情况
			strcpy(_str, str);

		}
~string()//析构函数
		{
			delete[] _str;
			_sz = _capacity = 0;
		}

c_str

const char* c_str() const //内部不修改的都要有右边加上const的习惯
		{
			return _str;
			
		}

返回大小和容量和扩容

size_t size()const//返回大小
		{
			return _sz;
		}
		size_t capactiy()const//返回大小
		{
			return _capacity;
		}
void reserve(size_t n)
		{
			if (n > _capacity)//不缩容
			{

				char* newcapacity = new char[n+1];//多开一个放\0
				strcpy(newcapacity, _str);
				delete[] _str;

				_str = newcapacity;
				
				_capacity = n;
			}
		}

访问(operaotr[])

char operator[](size_t pos)const
		{
			assert(pos < _sz);
			return _str[pos];
		}

尾插追加

void push_back(const char ch)
		{
			if (_sz == _capacity)
			{
				reserve(_capacity * 2);
				_capacity *= 2;
			}
			_str[_sz++] = ch;
			_str[_sz] = '\0';
		}
		void append(const char* s)
		{
			int len = strlen(s);
			if (_sz+len > _capacity)
			{
				reserve(_sz + len);
			}
			strcpy(_str + _sz, s);
			_sz += len;
		}
		string& operator+=(const char* s)
		{
			append(s);
			return *this;

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

		}

insert

void insert(size_t pos,const char ch)
		{
			assert(pos <= _sz);

			if (_sz == _capacity)
			{
				reserve(_capacity * 2);
				_capacity *= 2;
			}
			int end = _sz+1 ;//注意:int和size_t比会有整型提升,比不了,所以我们这里避免比较<、>的情况,终止条件为等于,所以end的位置得往前一位
			
			while (end > pos)
			{
				_str[end] = _str[end - 1];
				end--;
			}
			_str[pos] = ch;
			_sz++;
		}
void insert(size_t pos, const char* str)
		{
			assert(pos <= _sz);

			int len = strlen(str);
			if (_sz + len > _capacity)
			{
				reserve(_sz + len);
			}
			int end = _sz + 1;

			while (end > pos) 
			{
				_str[end +len-1] = _str[end-1];
				end--;
			}
			strncpy(_str+pos, str, len);//防止把'\0'拷贝进来
			_sz += len;
		}

erase和clear

void erase(int first, int last)
		{
			assert(first >= 0 && last <= _sz && first <= last);
			int len = last - first+1;
			
				char* tmp = new char[_sz];
				size_t i = 0;
				//左区间
				for ( i = 0; i < first; i++)
				{
					tmp[i] = _str[i];
				}
				//右区间
				for (size_t j = last+1; j < _sz; j++,i++)
				{
					tmp[i] = _str[j];
				}
				_sz -= len;
				tmp[_sz] = '\0';
				_str = tmp;
			
		}
 void _erase(size_t pos, size_t len = npos)
		{
			assert(pos <= _sz);
			if (len == npos || pos + len  >= _sz)
			{
				_str[pos] = '\0';
				_sz = pos;
			}
			else
			{
				int begin = pos + len;
				while (begin <=_sz)
				{
					_str[begin - len] = _str[begin];
					begin++;
				}
				_sz -= len;
			}
		}
void clear()
		{
			_str[0] = '\0';
			_sz = 0;
		}

resize

void resize(size_t n, const char ch = '\0')
		{
			if (n <= _sz)
			{
				_str[n] = '\0';
				_sz = n;
			}
			else
			{
				while (_sz < n)
				{
					_str[_sz++] = ch;
				}
				_str[_sz] = '\0';
			}
		}

find

size_t find(const char* str, size_t pos = 0)
		{
			const char* p = strstr(_str + pos, str);
			if (p)
			{
				return p - _str;
			}
			else
				return npos;
		}

substr

string substr(size_t pos, size_t len = npos)
		{
			int end = pos + len;
			string s;
			if (len == npos || pos + len >= _sz)//如果要拷贝的字串超过剩余的字符串长度
			{
				len = _sz - pos;
				end = _sz;
			}
			for (size_t i = pos; i < end; i++)
			{
				s += _str[i];
			}
			return s;
		}

运算符重载以及赋值

bool operator<(const string& s)const
		{
			return strcmp(_str, s._str) < 0;
		}
		bool operator==(const string& s)const
		{
			return strcmp(_str, s._str) == 0;
		}
		bool operator<=(const string& s)const
		{
			return *this < s._str || *this == s._str;
		}
		bool operator>=(const string& s)const
		{
			return !(*this < s._str);
		}
		bool operator>(const string& s)const
		{
			return  !(*this <= s._str);
		}

//赋值版本一
		string& operator=(const string& s)
		{
			if (this != &s)
			{
				char* tmp = new char[s._capacity];
				delete[] _str;
				_str = tmp;
				_sz = s._sz;
				_capacity = s._capacity;
			}
			return *this;
		}
		//赋值版本二
		string& operator=(string& s)
		{
			swap(s);
			return *this;
		}

流插入

ostream& operator<<(ostream& out, const string& s)
	{
	/*	for (size_t i = 0; i < s.size(); i++)
		{
			cout << s[i];
		}*/
		for (auto ch : s)
			cout << ch;
		return out;
	}

流提取

//流提取(版本一)
	istream& operator>>(istream& in, string& s)
	{
		s.clear();
		char ch;
		ch = in.get();//相当于getchar
		while (ch != ' ' && ch != '\n')
		{
			s += ch;
			ch = in.get();
		}
		return in;
	}

//流提取(版本二优化扩容问题)
	istream& operator>>(istream& in, string& s)
	{
		s.clear();
		char buff[128];
		int i = 0;
		char ch;
		ch = in.get();//相当于getchar
		while (ch != ' ' && ch != '\n')
		{
			buff[i++] = ch;
			if (i == 128)
			{
				buff[i] = '\0';
				s += buff;
				i = 0;
			}
			ch = in.get();
		}
		if (i != 0)
		{
			buff[i] = '\0';
			s += buff;
		}
		return in;
	}

swap

	void swap(string& s)
		{
			std::swap(_str, s._str);
			std::swap(_sz, s._sz);
			std::swap(_capacity, s._capacity);
		}

拷贝构造函数

string(const string& s)//拷贝构造(打工人写法)
			:_str(nullptr)//要初始化为空指针,因为待会free _str,_str不能为随机值
			,_sz (0)
			,_capacity(0)
		{
			free(_str);//先释放原空间
			_str = new char[s._capacity];
			strcpy(_str, s._str);
			_sz = s._sz;
			_capacity = s._capacity;
		}

string(const string& s)//拷贝构造(现代写法)
			:_str(nullptr)//要初始化为空指针,因为待会free _str,_str不能为随机值
			, _sz(0)
			, _capacity(0)
		{
			string tmp(s._str);
			swap(tmp);
		}

string.h

#pragma once
#include 
#include 
using namespace std;
namespace Space
{
	class string
	{
	public:
		typedef char* iterator;
		typedef const char* const_iterator;//常量迭代器

		iterator begin()
		{
			return _str;
		 }
		iterator end()
		{
			return _str+_sz;
		}
		const_iterator begin()const
		{
			return _str;
		}
		const_iterator end()const
		{
			return _str + _sz;
		}
		void swap(string& s)
		{
			std::swap(_str, s._str);
			std::swap(_sz, s._sz);
			std::swap(_capacity, s._capacity);
		}

		string(const char* str = "") //构造函数
			:_sz(strlen(str))
			, _capacity(_sz)
		{
			_str = new char[_capacity==0?4:_capacity+1];//防止_capacity为0情况
			strcpy(_str, str);

		}
		string(const string& s)//拷贝构造(现代写法)
			:_str(nullptr)//要初始化为空指针,因为待会free _str,_str不能为随机值
			, _sz(0)
			, _capacity(0)
		{
			string tmp(s._str);
			swap(tmp);
		}
		//string(const string& s)//拷贝构造(打工人写法)
		//	:_str(nullptr)//要初始化为空指针,因为待会free _str,_str不能为随机值
		//	,_sz (0)
		//	,_capacity(0)
		//{
		//	free(_str);//先释放原空间
		//	_str = new char[s._capacity];
		//	strcpy(_str, s._str);
		//	_sz = s._sz;
		//	_capacity = s._capacity;
		//}
		~string()//析构函数
		{
			delete[] _str;
			_sz = _capacity = 0;
		}
		const char* c_str() const //内部不修改的都要有右边加上const的习惯
		{
			return _str;
			
		}
		size_t size()const//返回大小
		{
			return _sz;
		}
		size_t capactiy()const//返回大小
		{
			return _capacity;
		}
		char operator[](size_t pos)const
		{
			assert(pos < _sz);
			return _str[pos];
		}
		void reserve(size_t n)
		{
			if (n > _capacity)//不缩容
			{

				char* newcapacity = new char[n+1];//多开一个放\0
				strcpy(newcapacity, _str);
				delete[] _str;

				_str = newcapacity;
				
				_capacity = n;
			}
		}
		void push_back(const char ch)
		{
			if (_sz == _capacity)
			{
				reserve(_capacity * 2);
				_capacity *= 2;
			}
			_str[_sz++] = ch;
			_str[_sz] = '\0';
		}
		void append(const char* s)
		{
			int len = strlen(s);
			if (_sz+len > _capacity)
			{
				reserve(_sz + len);
			}
			strcpy(_str + _sz, s);
			_sz += len;
		}
		string& operator+=(const char* s)
		{
			append(s);
			return *this;

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

		}
		void insert(size_t pos,const char ch)
		{
			assert(pos <= _sz);

			if (_sz == _capacity)
			{
				reserve(_capacity * 2);
				_capacity *= 2;
			}
			int end = _sz+1 ;//注意:int和size_t比会有整型提升,比不了,所以我们这里避免比较<、>的情况,终止条件为等于,所以end的位置得往前一位
			
			while (end > pos)
			{
				_str[end] = _str[end - 1];
				end--;
			}
			_str[pos] = ch;
			_sz++;
		}
		void insert(size_t pos, const char* str)
		{
			assert(pos <= _sz);

			int len = strlen(str);
			if (_sz + len > _capacity)
			{
				reserve(_sz + len);
			}
			int end = _sz + 1;

			while (end > pos) 
			{
				_str[end +len-1] = _str[end-1];
				end--;
			}
			strncpy(_str+pos, str, len);//防止把'\0'拷贝进来
			_sz += len;
		}
		
     	void erase(int first, int last)
		{
			assert(first >= 0 && last <= _sz && first <= last);
			int len = last - first+1;
			
				char* tmp = new char[_sz];
				size_t i = 0;
				//左区间
				for ( i = 0; i < first; i++)
				{
					tmp[i] = _str[i];
				}
				//右区间
				for (size_t j = last+1; j < _sz; j++,i++)
				{
					tmp[i] = _str[j];
				}
				_sz -= len;
				tmp[_sz] = '\0';
				_str = tmp;
			
		}
		void _erase(size_t pos, size_t len = npos)
		{
			assert(pos <= _sz);
			if (len == npos || pos + len  >= _sz)
			{
				_str[pos] = '\0';
				_sz = pos;
			}
			else
			{
				int begin = pos + len;
				while (begin <=_sz)
				{
					_str[begin - len] = _str[begin];
					begin++;
				}
				_sz -= len;
			}
		}
		void clear()
		{
			_str[0] = '\0';
			_sz = 0;
		}
		void resize(size_t n, const char ch = '\0')
		{
			
			if (n <= _sz)
			{
				_str[n] = '\0';
				_sz = n;
			}
			else
			{
				while (_sz < n)
				{
					_str[_sz++] = ch;
				}
				_str[_sz] = '\0';
			}
		}
		size_t find(const char* str, size_t pos = 0)
		{
			const char* p = strstr(_str + pos, str);
			if (p)
			{
				return p - _str;
			}
			else
				return npos;
		}
		string substr(size_t pos, size_t len = npos)
		{
			int end = pos + len;
			string s;
			if (len == npos || pos + len >= _sz)//如果要拷贝的字串超过剩余的字符串长度
			{
				len = _sz - pos;
				end = _sz;
			}
			for (size_t i = pos; i < end; i++)
			{
				s += _str[i];
			}
			return s;
		}
		//运算符重载
		bool operator<(const string& s)const
		{
			return strcmp(_str, s._str) < 0;
		}
		bool operator==(const string& s)const
		{
			return strcmp(_str, s._str) == 0;
		}
		bool operator<=(const string& s)const
		{
			return *this < s._str || *this == s._str;
		}
		bool operator>=(const string& s)const
		{
			return !(*this < s._str);
		}
		bool operator>(const string& s)const
		{
			return  !(*this <= s._str);
		}
		//赋值版本一
		/*string& operator=(const string& s)
		{
			if (this != &s)
			{
				char* tmp = new char[s._capacity];
				delete[] _str;
				_str = tmp;
				_sz = s._sz;
				_capacity = s._capacity;
			}
			return *this;
		}*/
		//赋值版本二
		string& operator=(string& s)
		{
			swap(s);
			return *this;
		}
	private:
		char* _str;
		int _sz;
		int _capacity;
		const static size_t npos;
	};
	const  size_t  string::npos = -1;
	//流插入
	ostream& operator<<(ostream& out, const string& s)
	{
	/*	for (size_t i = 0; i < s.size(); i++)
		{
			cout << s[i];
		}*/
		for (auto ch : s)
			cout << ch;
		return out;
	}
	//流提取(版本一)
	//istream& operator>>(istream& in, string& s)
	//{
	//	s.clear();
	//	char ch;
	//	ch = in.get();//相当于getchar
	//	while (ch != ' ' && ch != '\n')
	//	{
	//		s += ch;
	//		ch = in.get();
	//	}
	//	return in;
	//}
	//流提取(版本二优化扩容问题)
	istream& operator>>(istream& in, string& s)
	{
		s.clear();
		char buff[128];
		int i = 0;
		char ch;
		ch = in.get();//相当于getchar
		while (ch != ' ' && ch != '\n')
		{
			buff[i++] = ch;
			if (i == 128)
			{
				buff[i] = '\0';
				s += buff;
				i = 0;
			}
			ch = in.get();
		}
		if (i != 0)
		{
			buff[i] = '\0';
			s += buff;
		}
		return in;
	}
	void Test_String1()
	{
		string s1 = "hello world";
		string::iterator it = s1.begin();
		while (it != s1.end())
		{
			cout << *it << " ";
			it++;
		}
		cout << endl;
		for (auto ch : s1)//它会完全替换成上述代码,begin和end不变,如果我们自己写的迭代器中函数名有不同都会导致替换后,找不到对应的函数
		{
			cout << ch << " ";
		}
	}
	void Test_String2()
	{
		string s1 = "hello world";
		//cin >> s1;
		//cout << s1.size() << endl;

		//s1.erase(1, 5);
		s1.resize(5);

		cout << s1 << endl;
	}
	void Test_String3()
	{
		string s1 = "asdasd1234czx56c";
		cin >> s1;
		string s2 = s1;
		cout << s1 << endl;
		cout << s2 << endl;
		cout << sizeof(s1) << endl;

	}

}


如上便是本期的所有内容了,如果喜欢并觉得有帮助的话,希望可以博个点赞+收藏+关注❤️ ,学海无涯苦作舟,愿与君一起共勉成长

在这里插入图片描述

你可能感兴趣的:(c++)