C++--String and String's Simulated Implementation

string

String is a string class that represents a string.
Cannot operate on multi-byte or side-length character sequences.

string class in standard library

Common Construction of string Class Objects

void  teststring()
{
	string s;//Construct empty string class object s
	string s1("good!!");//Constructing string Class Object s1 with Strings in c Format
	string s2(10, 'c');//Constructing string Class Object s3 with 10'c'
	string s4(s);//Copy structure s4
	string s5(s1, 2);//Using the first two characters of s1 to construct string object s5
}

Capacity operation of string object

  1. The underlying principle of size() is exactly the same as length().
  2. clear() simply empties the valid characters in the string without changing the size of the underlying space.
  3. resize() in changing the number of elements, if the number of elements is increased, it may change the size of the underlying capacity, if the element is reduced, the total size of the underlying space remains unchanged. resize(sizr_t n,char c) and resize(size_t n) are both about changing the valid character of a string to n. The former fills the redundant element space with the character'c'and the latter fills the redundant element space with 0.
  4. reserve(size_t res_arg=0): Reserve space for string without changing the number of effective elements. Reserve does not change the size of capacity when reserve parameters are smaller than the bottom space size of string.

Access operation of string class object

Function name Functional description
char& operator[] ( size_t pos ) Character returning pos position, const string class object call
const char& operator[] ( size_t pos ) const Character returning pos position, non-const string class object call
void TestString()
{
	string s1("hello!");
	const string s2("Hello!");
	cout << s1 << " " << s2 << endl;
	cout << s1[0] << " " << s2[0] << endl;
	s1[0] = 'H';
	//s2[2]='f'; compilation failure, const object cannot be modified
	cout << s1 << endl;

}

Modification of string class objects

Function name Functional description
void push_back(char c) Insert the character c after the string
string& append (const char* s) Append a string after the string
string& operator+=(const string& str) Append str to the string
string& operator+=(const char* s) Append s string after string
string& operator+=(char c) Append the character c after the string
const char* c_str( ) const Returns a C-format string
size_t find (char c, size_t pos = 0) const Look back for the character c from the pos position of the string and return the position of the character in the string
size_t rfind(char c, size_t pos = npos) Look forward for the character c from the pos position of the string and return the position of the character in the string
string substr(size_t pos = 0, size_t n = npos) const In str, start at the pos position, intercept n characters, and return them
  1. When adding characters after string s, the implementation of s.push_back/ s.append(1,c) and s+='c'are almost the same. Generally, += is used more, because += operation can not only connect a single character, but also a string.
  2. For string operations, reserve the space if you can approximately estimate how many strings there are.

Simulated implementation of string

#include<assert.h>
#include<iostream>
#include<stdlib.h>
using namespace std;
//Simulated implementation of string
class String
{

private:
	char* _str;
	size_t _capacity;
	size_t _size;
public:

	typedef char* Iterator;


	String(const char* str = "")
	{
		// If a nullptr pointer is passed to construct a string class object and the program is considered illegal, the following assertion is made here
		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* Cstr = new char[s._capacity + 1];
			strcpy(Cstr, s._str);
			
			delete[] _str;
			_str = Cstr;
			_size = s._size;
			_capacity = s._capacity;
		}
		return *this;
	}
	//Iterator
	Iterator Begin()
	{
		return _str;
	}
	Iterator End()
	{
		return _str + _size;
	}
	~String()
	{
		if (_str)
		{
			delete[] _str;
			_str = nullptr;
		}
	}
	//Capacity expansion
	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';
	}
	//Capacity expansion
	void Reserve(size_t NewCapacity)
	{
		if (NewCapacity > _capacity)
		{
			char* str = new char[NewCapacity + 1];
			strcpy(str, _str);

			delete[] _str;
			_str = str;
			_capacity = NewCapacity;
		}
	}

	//Functional realization
	//Insert character'c'
	void PushBack(char c)
	{
		if (_size == _capacity)
		{
			Reserve(_capacity * 2);
		}
		_str[_size++] = 'c';
		_str[_size] = '\0';
	}
	//Additional insertion of n c
	void Append(size_t n, char c)
	{
		for (size_t i = 0; i < n; i++)
		{
			PushBack(c);
		}
	}
	void Append(char* str)
	{
		int m = strlen(str);
		for (int i = 0; i < m; i++)
		{
			PushBack(str[i]);
		}
	}

	String& operator +=(char c)
	{
		PushBack(c);
		return *this;
	}
	String& operator +=(char* str)
	{
		Append(str);
		return *this;
	}
	//empty
	void Clear()
	{
		_size = 0;
		_str[_size] = '\0';
	}
	//exchange
	void Swap(String& s)
	{
		swap(_str, s._str);
		swap(_size, s._size);
		swap(_capacity, s._capacity);
	}
	//Returns a C string
	const char* C_str() const
	{
		return _str;
	}


	//capacity
	size_t Capacity() const
	{
		return _capacity;
	}
	//Size
	size_t Size() const
	{
		return _size;
	}
	//Sentence blank
	bool Empty()
	{
		return _size == 0;
	}
	//[]
	char& operator[] (size_t index)
	{
		assert(index < _size);
		return _str[index];
	}
	const char& operator[] (size_t index) const
	{
		assert(index < _size);
		return _str[index];
	}
	size_t Find(char c, size_t pos = 0) const
	{
		for (int i= pos ; pos < _size; i++)
		{
			if (_str[i] == c )
			{
				return i;
			}
		}
		return -1;
	}
	
	size_t Find(const char* s, size_t pos = 0) const
	{
		char* curstr = strstr(_str + pos, s);//Find the first occurrence of another string str2 in the string str1. If a matching string is found, the first matching string pointer is returned, otherwise NULL is returned.
		if (curstr != nullptr)
		{
			return curstr - _str;
		}
		return -1;
	}
	String& Insert(size_t pos,  const char c)
	{
		assert(pos < _size);
		if (_size == _capacity)
		{
			size_t NewC = _capacity == 0 ? 15 : _capacity * 2;
			Reserve(NewC);
		}

		size_t end = _size;
		while (end>pos)
		{
			_str[end] = _str[end - 1];
			end--;
		}
		_str[pos] = 'c';
		_str[++_size] = '\0';
		return *this;
	}
	String& Insert(size_t pos, const char* str)
	{
		int len = strlen(str);
		assert(pos < _size);
		if (_size+len > _capacity)
		{
			Reserve(_size + len);
		}
		size_t end = _size + len;
		while (end > pos + len - 1)  // pos  pos + len
		{
			_str[end] = _str[end - len];
			--end;
		}

		//Insert string
		while (*str)
		{
			_str[pos++] = *str;
			++str;
		}
		_size += len;
		return *this;
	}
	bool operator>(const String& s)
	{
		char* str1 = _str;
		char* str2 = s._str;
		while (*str1 == *str2)
		{
			str1++;
			str2++;
		}
		if (*str1>*str2)
		{
			return true;
		}
		else
			return false;
	}
	bool operator<=(const String& s)
	{
		if (_str > s._str)
		{
			return false;
		}
		else
			return true;
	}
	bool operator>=(const String& s)
	{
		if (_str < s._str)
		{
			return false;
		}
		else
			return true;
	}
	bool operator==(const String& s)
	{
		char* str1 = _str;
		char* str2 = s._str;
		while (*str1 == *str2)
		{
			str1++;
			str2++;
		}
		if (*str1==*str2)
		{
			return true;
		}
		else
			return false;
	}
	bool operator!=(const String& s)
	{
		if (_str == s._str)
		{
			return true;
		}
		else
			return false;
	}
private:
	friend ostream& operator<<(ostream& _cout, const String& s);

};
ostream& operator<<(ostream& _cout, const String& s)
{
	cout << s._str;
	return _cout;
}

//test
void Test1()
{
	
	String s;
	String s1("aabbccdd");
	String S2(s1);
	String S3 = S2;
	cout << s1.Capacity() << endl<<s1.C_str()<<endl;
	s1.PushBack('c');
	cout << s1<<endl;
	s1.Append(5, 'c');
	cout << s1 << endl;
	cout<<s1.Begin();
	cout << s.Empty();
	cout << s1[2];
	s1.Insert(2, 'c');
	cout << s1<<endl;

	s1.Insert(2, "abc");
	cout << s1 << endl;
	cout<<s1.Find('d',2);
	
	s1.Append("abc");
	s1.Reserve(2);
	s1.Reserve(20);
	s1.Resize(25,'c');
	s1.Clear();
}
int main()
{
	Test1();
	system("pause");
	return 0;
}

Posted by sandingmachine on Wed, 28 Aug 2019 02:29:28 -0700