模拟实现string类常用接口

代码如下:

char* StrStr(char* dest, char* src)
{
	char* pdest = dest;
	char* psrc = src;
	while (*pdest)
	{
		if (*pdest == *psrc)
		{
			char* mdest = pdest;
			char* msrc = psrc;
			while (*mdest && *msrc)  // a,   e
			{
				if (*mdest != *msrc)
					break;
				mdest++;
				msrc++;
			}
			if (*msrc == '\0')
				return pdest;
		}
		++pdest;
	}

	return nullptr;
}

class String
{
public:
	typedef char* iterator;
	typedef const char* const_iterator;

	//构造
	String(char* str = "")
	{
		_size = strlen(str);
		_str = new char[_size + 1];
		strcpy(_str, str);
		_capacity = _size;
	}

	String(const String& str)
		:_str(nullptr)
		, _size(0)
		, _capacity(0)
	{
		String tmp(str._str);
		Swap(tmp);
	}

	void Swap(String& str)
	{
		swap(_str, str._str);
		swap(_size, str._size);
		swap(_capacity, str._capacity);
	}

	String& operator=(String str)
	{
		Swap(str);
		return *this;
	}

	~String()
	{
		if (_str)
		{
			delete[] _str;
			_str = nullptr;
			_size = _capacity = 0;
		}
	}

	//访问 非const 调用: 可读可写
	char& operator[](size_t pos)
	{
		assert(pos < _size);
		return _str[pos];
	}

	//const 调用: 只读接口
	const char& operator[](size_t pos) const
	{
		assert(pos < _size);
		return _str[pos];
	}
	//返回第一个元素的位置, 可读可写
	iterator begin()
	{
		return _str;
	}
	//返回最后一个元素的下一个位置
	iterator end()
	{
		return _str + _size;
	}

	//返回第一个元素的位置, 可读可写
	const_iterator begin() const
	{
		return _str;
	}
	//返回最后一个元素的下一个位置
	const_iterator end() const
	{
		return _str + _size;
	}


	//只读
	const_iterator cbegin() const
	{
		return _str;
	}

	const_iterator cend() const
	{
		return _str + _size;
	}


	//容量
	size_t Size() const
	{
		return _size;
	}
	size_t Capacity();
	void resize(size_t sz, char c = '\0')
	{
		// sz > _capacity : 增容, 内容赋值
		if (sz > _capacity)
			reserve(sz);

		// _size < sz <= _capacity : 内容赋值
		if (sz > _size)
		{
			memset(_str + _size, c, sz - _size);
		}
		// sz <= _size
		_size = sz;
		_str[_size] = '\0';
	}
	void reserve(size_t n)
	{
		if (n > _capacity)
		{
			char* tmp = new char[n + 1];
			strcpy(tmp, _str);
			delete[] _str;
			_str = tmp;
			_capacity = n;
		}
	}

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

	//修改

	void push_back(char c)
	{
		检查容量
		//if (_size == _capacity)
		//{
		//	size_t newC = _capacity == 0 ? 15 : 2 * _capacity;
		//	reserve(newC);
		//}
		//_str[_size] = c;
		//++_size;
		//_str[_size] = '\0';
		insert(_size, c);
	}

	void Append(const char* str)
	{
		//int sz = strlen(str);
		//if (_size + sz > _capacity)
		//{
		//	reserve(_size + sz);
		//}
		 "123\0"  + "456\0"
		//strcpy(_str + _size, str);
		//_size += sz;
		insert(_size, str);
	}

	String& operator+=(char c)
	{
		push_back(c);
		return *this;
	}
	String& operator+=(const char* str)
	{
		Append(str);
		return *this;
	}
	String& operator+=(const String&  str)
	{
		Append(str._str);
		return *this;
	}

	void insert(size_t pos, char c)
	{
		assert(pos <= _size);
		//检查容量
		if (_size == _capacity)
		{
			size_t newC = _capacity == 0 ? 15 : 2 * _capacity;
			reserve(newC);
		}
		//移动元素; 从后向前移动,防止覆盖
		size_t end = _size + 1;
		// end >= pos : 头插死循环
		while (end > pos)
		{
			_str[end] = _str[end - 1];
			--end;
		}
		//插入
		_str[pos] = c;
		++_size;
	}
	void insert(size_t pos, const char* str)
	{
		assert(pos <= _size);
		int sz = strlen(str);
		if (_size + sz > _capacity)
			reserve(_size + sz);
		size_t end = _size + sz;
		while (end > pos + sz - 1)  // pos + sz
		{
			//_size  --->  _size + sz
			//pos   --->  pos + sz
			_str[end] = _str[end - sz];
			--end;
		}
		int i = 0;
		while (*str)
		{
			_str[pos + i] = *str++;
			++i;
		}
		_size += sz;
		//_str[_size] = '\0';
	}

	void erase(size_t pos, int len)
	{
		assert(pos < _size);
		// 5  10   15
		if (pos + len >= _size)
		{
			_size = pos;
			_str[_size] = '\0';
			return;
		}
		size_t start = pos + len;
		//从前向后一次移动
		while (start <= _size)
		{
			_str[start - len] = _str[start];
			++start;
		}
		_size -= len;
	}

	void erase(iterator it)
	{
		assert(it < end() && it >= begin());
		while (it != end())
		{
			*it = *(it + 1);
			++it;
		}
		--_size;
	}

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

	size_t find(char ch, size_t pos = 0)
	{
		for (int i = pos; i < _size; ++i)
		{
			if (ch == _str[i])
				return i;
		}

		return npos;
	}

	friend ostream& operator<<(ostream& _cout, const String& str);

private:
	static const size_t npos;
	char* _str;
	size_t _size;
	size_t _capacity;

};

const size_t String::npos = -1;

ostream& operator<<(ostream& _cout, const String& str)
{
	for (const auto& ch : str)
	{
		_cout << ch << " ";
	}
	_cout << "end" << endl;
	return _cout;
}

测试代码:

void testString1()
{
	String str("hello");
	String str2("world");
	String copy(str);
	str2 = str;
}

void testString2()
{
	String str("hello");
	for (int i = 0; i < str.Size(); ++i)
	{
		str[i] = 'a';
		cout << str[i] << " ";
	}
	cout << endl;

	//const String str2("hello");
	//for (int i = 0; i < str2.Size(); ++i)
	//{
	//	//str2[i] = 'a';
	//	cout << str2[i] << " ";
	//}
	//cout << endl;

	//范围for: 底层通过迭代器实现
	//for (const auto& ch : str)
	//{
	//	cout << ch << " ";
	//}
	//cout << endl;

	//String::iterator sit = str.begin();
	//while (sit != str.end())
	//{
	//	*sit = 'c';
	//	cout << *sit << " ";
	//	++sit;
	//}
	//cout << endl;

	//String::const_iterator csit = str.cbegin();
	//while (csit != str.cend())
	//{
	//	//*csit = 'b';
	//	cout << *csit << " ";
	//	++csit;
	//}
	//cout << endl;
}

void testString3()
{
	String s("hello");
	s.push_back('w');
	s.Append("orld 1234567890");
	s += 'a';
	s.operator+=('b');
	s += "efg";
	String s2;
	s2 += s;
	cout << s.c_str() << endl;
}

void testString4()
{
	String s;  // ""  
	s.resize(5, 'a');  //"aaaaa"  sz > _capacity
	s.resize(10, 'b');  // "aaaaabbbbb"  sz > _capacity
	s += 'c';   // "aaaaabbbbbc"  _capacity : 20
	s.resize(17, 'd');    //  "aaaaabbbbbcdddddd" _capacity > sz > _size
	s.resize(5, 'e');  // "aaaaa"  sz < _size
	s.resize(10);    // "aaaaa\0\0\0\0\0\0"
	cout << s.c_str() << "end" << endl;
	cout << s << endl;

}

void testString5()
{
	//String s("456");  // 456
	//s.insert(1, 'a');  // 4a56
	//s.insert(4, 'b');  // 4a56b
	//s.insert(0, '0');  // 04a56b

	String s("45690"); 
	s.insert(3, "78");  // 4567890
	s.insert(7, "1112"); // 45678901112
	s.insert(0, "123"); // 12345678901112
	s.erase(5, 2);   //  123458901112
	s.erase(0, 3);  //  458901112
	s.erase(8, 10); // 45890111
	s.erase(5, 3);  // 45890
	s.erase(s.begin()); // 5890
	s.erase(s.end() - 1); // 589
}


void testString6()
{
	char* str1 = "abcdabcdef123";
	char* str2 = "abcde";
	char* ret = StrStr(str1, str2);

	String s("0123456789");
	size_t pos = s.find("345");
}
//int main()
//{
//	//testString1();
//	//testString2();
//	//testString3();
//	//testString4();
//	//testString5();
//	testString6();
//	return 0;
//}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值