自己来实现一个String类?干货!!!!详细!!!!(补充)

在这里插入图片描述

这里对于String类的具体补充是让我们更加完善这个接口,在上一篇博客中 点击此处就是一个简单的手撕String,这里是补充,让我们对于String类的理解更加的深刻.

一.insert

1.插入字符

比较简单,就是要对于其后面的元素进行后移的操作,复杂度比较高
在这里插入图片描述

void  insert(size_t pos, const char& ch){
		
		//0.检查位置是否有效[0,size]
		assert(pos <= _size);

		//1.容量检查
		if (_size  == _capacity){
			
			size_t newc = _capacity == 0 ? 15 : 2 * _capacity;
			reserve(newc);
		}
		//2.从后向前移动元素(先将\0放在最后,以免最后的添加)
		size_t end = _size + 1;
		while (end > pos){
			
			_data[end] = _data[end - 1];
			--end;
		}
		//3.插入
		_data[pos] = ch;
		//4.更新
		_size++;
	}

这个函数的内部就是由很多简单的步骤组成的,我们多看看,多理解就行了.

2.插入字符串

步骤:
1.输入位置检查
2.容量检查
3.依次循环往后
4.插入
5.更新

这里就不做过多的解释了,其实完成一个字符串的插入就是相当于将每一个字符进行插入,多次形成一个循环就可以了.

void insert(size_t pos, const char* ptr){
		
		//输入检查
		assert(pos <= _size);

		//要插入字符串的长度
		int len = strlen(ptr);
		if (_size+len > _capacity){
			
			reserve(_size + len);	//如果内部的容量不够,则对其进行扩容
		}

		size_t end = _size + len;		//定义最后的位置
		while (end>pos+len-1){//在内部进行循环,让字符串挨个加上
			
			_data[end] = _data[end - len];	//按照对应的位置进行赋值
			--end;//挨个循环
		}
	   
		_size += len;	//对其位置进行更新
	}

二.erase

在这里插入图片描述

void erase(size_t pos, size_t len = npos){

		assert(pos < _size);		//输入的是否有效检查
		
		if (len == npos||pos+len>=_size){	
		//当存在输入的pos值大于或者等于其中的值时,直接对所有的进行删除
			_size = pos;
			_data[_size] = '\0';
		}
		else{		//如果输入的是有效字符

			size_t start = pos + len;	//先定义最后的位置

			//[pos+len,size]
			while (start <= _size){		//在要删除的循环内部

				//依次向前移动
				_data[start - len] = _data[start];		//将要删除后面的依次进行提前
				start++;	//循环
			}
			_size -= len;		//在直接对_size减去len 即可
		}
	}

//===============上面的代码需要下面的进行实现--定义了一个静态变量赋予了缺省值
class String{
public:
	...
private:
	size_t _size;
	size_t _capacity;
	char* _data;
	static const size_t npos;
};
//静态成员在外部进行定义
const size_t String::npos=-1;

删除基本上都牵扯到内存_size缩小

三.find

1.寻找对应字符数的位置

size_t find(const char& ch, size_t pos = 0){
		
		for (size_t i = pos; i < _size; ++i){

			if (_data[i] == ch)
				return i;
		}
		//越界
		return npos;
	}

2.寻找对应的字符串的位置

步骤:
1.看是否有效
2.利用C语言的strstr进行寻找
3.寻找到则输出对应的位置
4.没有寻找到则输出其所预先设好的缺省值

size_t find(const char* ptr, size_t pos = 0){
		
		assert(pos < _size);		//输入检查
		
		char* ptrPos=strstr(_data+pos, ptr);	//运用strstr函数找到对应的
		
		if (ptrPos){
			
			return ptrPos - _data;	//如果找到,则直接对其进行输出
		}
		return npos;	//如果没找到则输出缺省值,这里的npos是上面的函数私有类定义的静态变量
	}

四.选取字符串中的子串

步骤:

1.我们给定了开始的位置和长度
2.创建新的String空间
3.从pos位置开始进行memcpy拷贝过去
4.因为它会把POS后面的全部拷贝,我们只需要len
5.我们将len 长度时的值变为\0,让这个字符串强制结束
6.返回新创建的空间,删除原来的空间

在这里插入图片描述

String substr(size_t pos, size_t len=npos){
		
		assert(pos < _size);		//输入检查

		if (len==npos||pos + len >= _size){	
		//如果对应的字节是相等的话,责直接调用函数对其进行输出
			return String(_data + pos);
		}
		else{		//如果满足条件
			
			char* newC = new char[len+1];	//先开辟一个对应的空间

			memcpy(newC, _data + pos, sizeof(char)*len);	//将对应的字节拷贝过去
			newC[len] = '\0';		//对新的空间的最后位置赋予\0,因为在字符串里面都是以\0结尾的
			return String(newC);	//将洗的呢字符串进行输出
			delete[] newC;			//删除掉以前的字符串空间
		}
	}

五.赋值运符补充

operator >>

自定义输入操作

istream& operator>>(istream& in, String& str){
	
	char ch;		//定义一个字符串
	while (ch=cin.get()){	//利用grt函数接口,遇到空格时结束
		
		if (ch == ' ' || ch == '\n')	//等于对应的值时,直接退出
			break;
		//尾插
		str += ch;	//满足条件则直接尾插
	}
	return in;	//返回对应的值
}

operator <<

自定义输出操作

ostream& operator<<(ostream& out, const String& str){
	
	for (const auto& ch : str)	//直接使用一个范围for函数将其进行输出
		out << ch;
	return out;		//返回其值
}

这篇农科就是对上一篇博客的一个总结和补充,让String类的接口能更加的全面.不清楚的可以返回到上一篇博客看. 点击此处

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值