string的模拟实现

我们来模拟实现一下string类的常用接口啊,不是常用类的就不模拟实现了哦,没有见过,估计也半天想不出来啊。

  • 我们看一下string类的常见接口吧

函数名称 | 功能说明


string() | 构造string类空字符串
string(const char* s) | 构造字符串
string(size_t n char c) | string类包含n个字符串
string(const string&s) | 用s中前n个字符构造新的string类对象

void TestString() {    
	string s1;                // 构造空的string类对象s1    
	string s2("hello bit");   // 用C格式字符串构造string类对象s2    					     				

	string s3(10, 'a');      // 用10个字符'a'构造string类对象s3    
	string s4(s2);            // 拷贝构造s4   
	 string s5  (s3, 5);          //用s3中前5个字符构造string对象s5

函数名称 |功能说明


size_t size() | const 返回字符串有效字符长度
size_t length() | const 返回字符串有效字符长度
size_t capacity ( ) | const 返回空间总大小
bool empty ( ) const | 检测字符串释放为空串,是返回true,否则返回false
void clear() | 清空有效字符
void resize ( size_t n, char c ) | 将有效字符的个数该成n个,多出的空间用字符c填充
void resize ( size_t n ) | 将有效字符的个数改成n个,多出的空间用0填充
void reserve ( size_t res_arg=0 ) | 为字符串预留空间

// size/length/clear/resize 
void TestString1() { 
   // 注意:string类对象支持直接用cin和cout进行输入和输出    					
	string s("hello, bit!!!");   
	 cout<<s.length();  
	   cout << s.size() << endl;   
	    cout << s.capacity() << endl;   
	     cout << s <<endl;      
	       // 将s中的字符串清空,注意清空时只是将size清0,不改变底层空间的大小   
	        s.clear();  
	          cout << s.size() << endl; 
	           cout << s.capacity() << endl;
 
    // 将s中有效字符个数增加到10个,多出位置用'a'进行填充  
      // “aaaaaaaaaa”   
       s.resize(10, 'a');  
         cout << s.size() << endl;   
          cout << s.capacity() << endl;
 
    // 将s中有效字符个数增加到15个,多出位置用缺省值'\0'进行填充  
      // "aaaaaaaaaa\0\0\0\0\0"   
       // 注意此时s中有效字符个数已经增加到15个 
          s.resize(15);
         cout << s.size() << endl;    
         cout << s.capacity() << endl;    
         cout << s << endl;
 
    // 将s中有效字符个数缩小到5个    s.resize(5);    cout << s.size() << endl;
    cout << s.capacity() << endl; 

下面一些操作修改字符串接口就不显示了,这些大意多看看一些基本书籍应该都有一些描述,我只把接口列出来啊


| 函数名称 | 功能说明 |


char& operator[] ( size_t pos ) | 返回pos位置的字符,const string类对象调用
const char& operator[] | ( size_t pos ) const
返回pos位置的字符,非const string类对象调 用
void push_back(char c) | 在字符串后尾插字符c |
string& append (const char* s); | 在字符串后追加一个字符串 |
string& operator+=(const string& str)
| 在字符串后追加字符串str
string& operator+=(const char* s) | 在字符串后追加C个数字符串
string& operator+=(char c) | 在字符串后追加字符c
const char* c_str( )const | 返回C格式字符串
size_t find (char c, size_t pos = 0)const
| 从字符串pos位置开始往后找字符c,返回该字符在 字符串中的位置
size_t rfind(char c, size_t pos = npos)
| 从字符串pos位置开始往前找字符c,返回该字符在 字符串中的位置
string substr(size_t pos = 0, size_t n = npos)const
| 在str中从pos位置开始,截取n个字符,然后将其 返回

好了来演示一下代码吧!

namespace HWang
{
	class String
	{
	public:
		typedef char* Iterator;
	public:
		String(const char* str = "")
		{
			if (nullptr == str)
			{
				assert(false);
				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 PushBack(char c)
		{
			if (_size == _capacity)
				Reserve(_capacity * 2);
			_str[_size++] = c;
			_str[_size] = '\0';
		}
		void Append(size_t n, char c)
		{
			for (size_t i = 0; i < n; ++i)
				PushBack(c);
		}
		String& operator+=(char c)
		{
			PushBack(c);
			return *this;
		}
		void Append(const char* str);
		String& operator+=(const char* str);
		void Clear()
		{
			_size = 0;
			_str[_size] = '\n';
		}
		void Swap(String& s)
		{
			swap(_str, s._str);
			swap(_size, s._size);
			swap(_capacity, s._capacity);


		}
		const char* C_str()const
		{
			return _str;
		}
		size_t Size()const
		{
			return _size;
		}
		size_t Capacity()const
		{
			return _capacity;
		}
		bool Empty() const
		{
			return 0 == _size;
		}
		void Resize(size_t newSize, char c = char())
		{
			if (newSize > _size){
				if (newSize > _capacity)
				{
					Reserve(newSize);
				}
				memset(_str + _size, c, newSize - _size);

			}
			_size = newSize;
			_str[newSize] = '\0';
		}
		void Reserve(size_t newCapacity)
		{
			if (newCapacity > _capacity)
			{
				char* str = new char[newCapacity + 1];
				strcpy(str, _str);
				_str = str;
				_capacity = newCapacity;
			}
		}
		char& operator[](size_t index)
		{
			assert(index < _size);
			return _str[index];
		}
		int Find(char c, size_t pos = 0)
		{
			for (size_t i = pos; i < _size; ++i)
			{
				if (c == _str[i])
					return i;
			}
			return npos;
		}
			int rFind(char c)
			{
				for (int i = _size - 1; i > = 0; --i)
				{
					if (c == _str[i])
						return i;
				}
				return npos;
			}
			String StrSub(size_t pos, size_t size)
			{
				int len = strlen(_str + pos);
				if (size > len)
					size = len;
				return String(_str + pos, size);
			}
	private:
		friend ostream& operator<<(ostream& _cout, const bit::String& s);
	private:
		char* _str;
		size_t _capacity;
		size_t _size;

		const int String::npos = -1;
	};

}
ostream& bit::operator<< (ostream& _cout, const bit::String& s){
	cout << s._str;
	return _cout;
}
void TestHwangString1() {
	bit::String s1;    
	bit::String s2("hello bit");
	bit::String s3(s2);

	s1 = s3;   
	cout << s1 << endl;   
	cout << s2 << endl;
	cout << s3 << endl;
}

void TestHWangString2() {
	bit::String s1("hello");   
	s1.PushBack(' '); 
	s1.PushBack('b');   
	s1.Append(1, 'i');   
	s1 += 't';   
	cout << s1 << endl;
	cout << s1.Size() << endl;
	cout << s1.Capacity() << endl;

	// 利用迭代器打印string中的元素    
	auto it = s1.Begin();    
	while (it != s1.End())   
	{      
		cout << *it++;   
	}
	cout << endl;

	bit::String s2("hello world!!!");  
	s1.Swap(s2);
	cout << s1 << endl; 
	cout << s2 << endl;
}

void TestHWangString3() {
	bit::String s("hello");   
	cout << s << endl;  
	cout << s.Size() << endl;   
	cout << s.Capacity() << endl;

	s.Resize(10, 'a');   
	cout << s << endl; 
	cout << s.Size() << endl;
	cout << s.Capacity() << endl;

	s.Resize(20);  
	cout << s << endl;    
	cout << s.Size() << endl;   
	cout << s.Capacity() << endl;

	s.Resize(5);
	cout << s << endl;   
	cout << s.Size() << endl;   
	cout << s.Capacity() << endl;

	s.Reserve(50); 
	cout << s << endl;  
	cout << s.Size() << endl; 
	cout << s.Capacity() << endl;
}

int main()
{
	TestHwangString1();
	TestHwangString2();
	TestHwangString3();


}

我们的基本思想是把string换算成我们的c语言字符串,先就算出来string类的size大小,然后在根据实际情况完成string类空间容量的分配,超过空间模拟vs或者c++的增容方式重新增容,没有超过则不用。计算寻找字符串中某一个位置,或者修改某一个位置时候,就需要用到c++里面的operator赋值运算符的重载主要思想也就围绕这两点吧,其他的我们一时间想不起来,一个也就这些,string模拟实现相比之下逻辑方面其实不是很绕,稍微想一下主要知道这个接口怎么用,应该用简简单单方法都可以实现的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值