首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >string的模拟实现

string的模拟实现

作者头像
用户11290664
发布2025-01-20 17:55:33
发布2025-01-20 17:55:33
8900
代码可运行
举报
文章被收录于专栏:学习学习
运行总次数:0
代码可运行

模拟实现类

一string的底层逻辑

代码语言:javascript
代码运行次数:0
运行
复制
#pragma once
#include<iostream>
#include<assert.h>
namespace Z {
	class string {
	public:
		


		string(const char* str="");//""就是\0的意思

		~string();
		}
代码语言:javascript
代码运行次数:0
运行
复制
#define  _CRT_SECURE_NO_WARNINGS 1
#include"string.h"
namespace Z {

	//string::string()
	//	:_size(0)
	//	, _capacity(0)
	//	, _str(new char [1] {'\0'})
	//{

	//}
	string::string(const char* str)
		:_size(strlen(str))//都用模板的话要和定义顺序对齐,所以这里只使用一个模板
	{
		_capacity = _size;
		_str = new char[_size + 1];//永远多开一个空间要存'\0'
		strcpy(_str, str);
	}
	string::~string() {
		delete[]_str;
		_str = nullptr;
		_size = 0;
		_capacity = 0;


	}

二模拟函数

(1)reserve

这里要构造个tmp插入后销毁原来数据

代码语言:javascript
代码运行次数:0
运行
复制
void string::reserve(int n)
{
	if (n > _capacity) {
		char* tmp = new char[n + 1];//多开一个放'\0'
		strcpy(tmp, _str);
		delete(_str);
		_str = tmp;
		_capacity = n;



	}



}

(2)push_back append

这两个函数要进行尾插

代码语言:javascript
代码运行次数:0
运行
复制
void string::push_back(char ch) {
	if (_size == _capacity) {
		reserve(_capacity==0?4:_size * 2);
	}
	_str[_size] = ch;
	_size++;
	

}
void string::append(const char* str) {
	int newcapacity;
	if (_size + strlen(str) > _capacity) {
		 newcapacity = _capacity * 2;



	}
	if (newcapacity < _size + strlen(str)) {
		newcapacity = _size + strlen(str);
	}
	reserve(newcapacity);
	strcpy(_str + _size, str);
	_size = _size + strlen(str);
}

(3)+=

代码语言:javascript
代码运行次数:0
运行
复制
	string& string::operator+=(char ch) {
		push_back(ch);
		return *this;
	}
	string& string::operator+=(const char* str) {

		append(str);
		return *this;
	}

(4)insert

但是头插会出错 pos是size_t 不会为负数,所以要改成int 然后还不行判断条件是end>=pos但是数据类型也不一致 范围小一般向范围大的进行提升 有符号会提升成无符号 然后再把pos强转成int

或者换个方式

先扩容

但是这样也是错的

不想强转的也可以直接用第二种方法 还有就是insert不建议用,时间复杂度太低

npos

一般const成员变量不能在声明定义,但是整型npos可以

(5)erase

如果 (len==npos||len>=_size-pos) 这就是pos后面位置全部删除 {_str[pos]=‘\0’; _size=pos; }

(6)find

注意自己赋值给自己的情况

非成员函数的原因

<<和>>自定类型要自己写

getlin

这里要取一段文字后第一段空格后的字母个数必须要用getlin提取,因为用cin的话会遇到‘ ’终止

三遍历

(1)[ ]

代码语言:javascript
代码运行次数:0
运行
复制
char& operator[](size_t i) {
	assert(i < _size);
		return _str[i];


}

这里可以通过[]修改不是const修饰的str. 也有不能修改的

代码语言:javascript
代码运行次数:0
运行
复制
	const char& operator[](size_t i)const {
		assert(i < _size);
		return _str[i];


	}

(2)迭代器

先定义迭代器和反向迭代器 typedef char* iterator; using reverse_iterator = const char*;

这里也分两种

代码语言:javascript
代码运行次数:0
运行
复制
		//迭代器的遍历
		iterator begin() {
			return _str;
		}
		iterator end() {
			return _str+_size;
		}
		const reverse_iterator begin()const {
			return _str;
		}
		const reverse_iterator end()const {
			return _str + _size;
		}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-01-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 模拟实现类
  • 一string的底层逻辑
  • 二模拟函数
  • (1)reserve
  • (2)push_back append
  • (3)+=
  • (4)insert
  • npos
  • (5)erase
  • (6)find
  • getlin
  • 三遍历
  • (1)[ ]
  • (2)迭代器
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档