当前位置: 首页 > article >正文

string的实现(下)

1.面试中的简单实现

在面试中,由于时间的缘故,我们只需要简单实现string就行,其中就包括构造函数,析构函数,拷贝构造,赋值运算即可。由于不涉及容量的改变,只需要一个成员变量_str即可。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class my_string
{
public:
	my_string(const char* s = "")
		:_str(new char[strlen(s)+1])
	{
		strcpy(_str, s);
	}//构造函数

	my_string(const my_string& s)
		:_str(nullptr)
	{
		my_string s1(s.c_str());
		swap(_str, s1._str); //交换首地址元素,结束旧元素的s1,会自动调用析构函数析构,一定要置原_str为空,不然就会析构错误
	}//拷贝构造函数

	~my_string()
	{
		delete[] _str;
		_str = nullptr;
	}
	//析构函数

	my_string& operator=(const my_string& s)
	{
		my_string s1(s);
		swap(_str, s1._str);
		return *this;
	}

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

2.复杂功能的实现

注意,其中可能掺杂了strcpy的来交换_str的传统写法,我们更倾向于在实现的时候调用库函数swap。

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<assert.h>
using namespace std;

class my_string
{
	friend istream& operator>>(istream& ci, my_string& s);
public:
	my_string(const char* s="")
	{
		_size = _capacity = strlen(s);
		_str = new char[_size + 1];
		strcpy(_str, s);
	}//实现了默认和带参构造
	//my_string(const my_string& s)
	//{
	//	_size = _capacity = strlen(s._str);
	//	_str = new char[_size + 1];
	//	strcpy(_str, s._str);

	//}//实现拷贝构造
	
	//拷贝构造的现代写法(使用swap)
	my_string(const my_string& s)
		:_str(nullptr) //如果初始化 换给s中的str后,s析构delete时就会出问题
	{
		my_string tmps(s._str);
		swap(tmps);
	}
	~my_string()
	{
		delete[] _str;
		_capacity = _size = 0;
		_str = nullptr;
	}
	char& operator[](size_t pos)const
	{
		assert(pos >= 0 && pos < _size);
		return *(_str + pos);
	}
	typedef char* iterator;

	char* begin()const
	{
		return _str;
	}

	char* end()const
	{
		return _str + _size ;
	}

	void push_back(char c)
	{
		if (_capacity == _size)
		{
			size_t capacity = _capacity == 0 ? 4 : 2 * _capacity;
			reserve(capacity);
		}
		_str[_size++] = c;
		_str[_size] = '\0';
	}
	void append(const char* s)
	{
		size_t len = strlen(s);
		if (_size + len > _capacity)
		{
			size_t capacity =  _size + len;
			reserve(capacity);
		}
		strcpy(_str + _size, s);
		_size = _size + len;
	}
	void operator+=(char c)
	{
		push_back(c);
	}
	void operator+=(const char* str)
	{
		append(str);
	}
	void reserve(size_t n)
	{
		if (n > _capacity)
		{
			char* tmp = new char[n + 1];
			strcpy(tmp, _str);
			delete[] _str;
			_str = tmp;
			_capacity = n;
		}
	}
	void resize(size_t n,char c = '\0')
	{
		if (n <= _size)
		{
			_str[n] = '\0';
		}
		else
		{
			reserve(n);
			for (size_t i = _size; i < n; i++)
			{
				_str[i] = c;
			}
			_str[n] = '\0';
		}
	}
	my_string& insert(size_t pos, size_t n, char c)
	{
		assert(pos <= _size);
		if (_capacity < _size + n)
		{
			reserve(_size + n);
		}//先增容
		int end = _size;
		while (end >= (int)pos)
		{
			_str[end + n] = _str[end];
			end--;
		}//将pos位置后的移动,腾出n个位置
		while (n)
		{
			_str[pos] = c;
			pos++;
			n--;
		}
		return *this;
	}
	my_string& insert(size_t pos, const char* str)
	{
		assert(pos <= _size);
		size_t len = strlen(str);
		if (_capacity < _size + len)
		{
			reserve(_size + len);
		}//扩容
		int end = _size;
		while (end >= (int)pos)
		{
			_str[end + len] = _str[end];
			end--;
		}//腾位置
		strncpy(_str + pos, str, len);
		return *this;
	}

	my_string erase(size_t pos, size_t len = npos)
	{
		assert(pos < _size);
		if (len >= _size - pos)
		{
			_str[pos] = '\0';
			_size = pos;
		}
		else
		{
			for (size_t i = pos + len; i <= _size; i++)
			{
				_str[i - len] = _str[i];
			}
		}
		return *this;
	}
	size_t find(char c, size_t pos = 0)const
	{
		assert(pos < _size);
		for (size_t i = pos; i < _size; i++)
		{
			if (_str[i] == c)
			{
				return i;
			}
		}
		return npos;
	}
	size_t find(const char* str, size_t pos = 0)const
	{
		assert(pos < _size);
		const char* s = strstr(_str + pos, str);
		if (s)
		{
			return s - begin();
		}
		return npos;
	}
	//my_string& operator=(const my_string& s)
	//{
	//	delete[] _str;
	//	char* tmp = new char[strlen(s._str) + 1];
	//	strcpy(tmp, s._str);
	//	_str = tmp;
	//	return *this;
	//}

	// operator=的现代写法(使用swap)

	///*my_string & operator=(const my_string & s)
	//{
	//	my_string s1(s);
	//	swap(s1);
	//}*/
	my_string& operator=(my_string s)
	{
		swap(s);
		return *this;
	}
	bool operator==(const my_string& s)const
	{
		int c = strcmp(_str, s._str);
		return c == 0;
	}
	bool operator> (const my_string& s)const
	{
		int c = strcmp(_str, s._str);
		return c > 0;
	}
	bool operator< (const my_string& s)const
	{
		int c = strcmp(_str, s._str);
		return c < 0;
	}
	bool operator>=(const my_string& s)const
	{
		return !(*this < s);
	}
	bool operator<=(const my_string& s)const
	{
		return !(*this > s);
	}
	size_t size()const
	{
		return _size;
	}
	size_t capacity()const
	{
		return _capacity;
	}

	char* c_str() const
	{
		return _str;
	}
	void swap(my_string& s)
	{
		::swap(_str, s._str); //_str指向的是地址,所以库的swap实现了首元素地址交换,就交换了整个
		::swap(_size, s._size);
		::swap(_capacity, s._capacity);
	}
private:
	char* _str;
	size_t _size;//已经有多少有效字符
	size_t _capacity;//能存储多少有效字符

	static size_t npos;
};

size_t my_string::npos = -1;

ostream& operator<<(ostream& cou, const my_string& s)
{
	cout << s.c_str();
	return cou;
}
istream& operator>>(istream& ci, my_string& s)
{
	while (1)
	{
		char c;
		c=ci.get();
		if (c == '\0' || c == '\n')
		{
			break;
		}
		else
		{
			s.push_back(c);
		}
	}
	return ci;
	
}//利用istream中的get获取单个字符


http://www.kler.cn/news/331387.html

相关文章:

  • 会议平台后端优化方案
  • 如何在 DAX 中计算多个周期的移动平均线
  • 第二十二章 rust数据库使用:sea-orm详解
  • 【有啥问啥】表示学习(Representation Learning)详解:理论、方法与应用
  • 新品:新一代全双工音频对讲模块SA618F22-C1
  • 【JVM】垃圾释放方式:标记-清除、复制算法、标记-整理、分代回收
  • Oracle datafile 数目限制是多少
  • rsync数据备份实时同步
  • Linux中find命令详解
  • PHP常用的超全局变量(8个)
  • WebSocket 2024/9/30
  • MATLAB使用眼图分析QPSK通信系统接收端匹配滤波后的信号
  • windows 11 LTSC 26100.1742 官方简体中文版
  • 免杀对抗—GOC#反VT沙盒资源分离混淆加密
  • 【Flutter】- 基础语法
  • 【go入门】常量
  • Leetcode 11.乘最多水的容器(字节,快手面试题)
  • 探索Spring Boot:实现“衣依”服装电商平台
  • 【Java序列化】使用Java 自带的Serializer进行对象序列化和反序列化
  • 2024年OpenAI DevDay发布实时 API、提示缓存等新功能