1. 程式人生 > >string的模擬實現

string的模擬實現

我們來模擬實現一下string類的常用介面啊,不是常用類的就不模擬實現了哦,沒有見過,估計也半天想不出來啊。

  • 我們看一下string類的常見介面吧

函式名稱 | 功能說明


string() | 構造string類空字串
string(const char* s) | 構造字串
string(size_t n char c) | string類包含n個字串
string(const string&s) | 用s中前n個字元構造新的string類物件

void TestString() {    
	string s1;                // 構造空的string類物件s1    
	string s2("hello bit");   // 用C格式字串構造string類物件s2    					     				

	string s3(10, 'a');      // 用10個字元'a'構造string類物件s3    
	string s4(s2);            // 拷貝構造s4   
	 string s5  (s3, 5);          //用s3中前5個字元構造string物件s5

函式名稱 |功能說明


size_t size() | const 返回字串有效字元長度
size_t length() | const 返回字串有效字元長度
size_t capacity ( ) | const 返回空間總大小
bool empty ( ) const | 檢測字串釋放為空串,是返回true,否則返回false
void clear() | 清空有效字元
void resize ( size_t n, char c ) | 將有效字元的個數該成n個,多出的空間用字元c填充
void resize ( size_t n ) | 將有效字元的個數改成n個,多出的空間用0填充
void reserve ( size_t res_arg=0 ) | 為字串預留空間

// size/length/clear/resize 
void TestString1() { 
   // 注意:string類物件支援直接用cin和cout進行輸入和輸出    					
	string s("hello, bit!!!");   
	 cout<<s.length();  
	   cout << s.size() << endl;   
	    cout << s.capacity() << endl;   
	     cout << s <<endl;      
	       // 將s中的字串清空,注意清空時只是將size清0,不改變底層空間的大小   
	        s.clear();  
	          cout << s.size() << endl; 
	           cout << s.capacity() << endl;
 
    // 將s中有效字元個數增加到10個,多出位置用'a'進行填充  
      // “aaaaaaaaaa”   
       s.resize(10, 'a');  
         cout << s.size() << endl;   
          cout << s.capacity() << endl;
 
    // 將s中有效字元個數增加到15個,多出位置用預設值'\0'進行填充  
      // "aaaaaaaaaa\0\0\0\0\0"   
       // 注意此時s中有效字元個數已經增加到15個 
          s.resize(15);
         cout << s.size() << endl;    
         cout << s.capacity() << endl;    
         cout << s << endl;
 
    // 將s中有效字元個數縮小到5個    s.resize(5);    cout << s.size() << endl;
    cout << s.capacity() << endl; 

下面一些操作修改字串介面就不顯示了,這些大意多看看一些基本書籍應該都有一些描述,我只把介面列出來啊


| 函式名稱 | 功能說明 |


char& operator[] ( size_t pos ) | 返回pos位置的字元,const string類物件呼叫
const char& operator[] | ( size_t pos ) const
返回pos位置的字元,非const string類物件調 用
void push_back(char c) | 在字串後尾插字元c |
string& append (const char* s); | 在字串後追加一個字串 |
string& operator+=(const string& str)
| 在字串後追加字串str
string& operator+=(const char* s) | 在字串後追加C個數字串
string& operator+=(char c) | 在字串後追加字元c
const char* c_str( )const | 返回C格式字串
size_t find (char c, size_t pos = 0)const
| 從字串pos位置開始往後找字元c,返回該字元在 字串中的位置
size_t rfind(char c, size_t pos = npos)
| 從字串pos位置開始往前找字元c,返回該字元在 字串中的位置
string substr(size_t pos = 0, size_t n = npos)const
| 在str中從pos位置開始,擷取n個字元,然後將其 返回

好了來演示一下程式碼吧!

namespace HWang
{
	class String
	{
	public:
		typedef char* Iterator;
	public:
		String(const char* str = "")
		{
			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* pstr = new char[s._capacity + 1];
				strcpy(pstr, s._str);
				delete[]_str;
				_str = pstr;
				_size = s._size;
				_capacity = s._capacity;
			}
			return *this;
		}
		~String()
		{
			if (_str)
			{
				delete[] _str;
				_str = nullptr;
			}
		}
		Iterator Begin()
		{
			return _str;
		}
		Iterator End()
		{
			return _str + _size;
		}
		void PushBack(char c)
		{
			if (_size == _capacity)
				Reserve(_capacity * 2);
			_str[_size++] = c;
			_str[_size] = '\0';
		}
		void Append(size_t n, char c)
		{
			for (size_t i = 0; i < n; ++i)
				PushBack(c);
		}
		String& operator+=(char c)
		{
			PushBack(c);
			return *this;
		}
		void Append(const char* str);
		String& operator+=(const char* str);
		void Clear()
		{
			_size = 0;
			_str[_size] = '\n';
		}
		void Swap(String& s)
		{
			swap(_str, s._str);
			swap(_size, s._size);
			swap(_capacity, s._capacity);


		}
		const char* C_str()const
		{
			return _str;
		}
		size_t Size()const
		{
			return _size;
		}
		size_t Capacity()const
		{
			return _capacity;
		}
		bool Empty() const
		{
			return 0 == _size;
		}
		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';
		}
		void Reserve(size_t newCapacity)
		{
			if (newCapacity > _capacity)
			{
				char* str = new char[newCapacity + 1];
				strcpy(str, _str);
				_str = str;
				_capacity = newCapacity;
			}
		}
		char& operator[](size_t index)
		{
			assert(index < _size);
			return _str[index];
		}
		int Find(char c, size_t pos = 0)
		{
			for (size_t i = pos; i < _size; ++i)
			{
				if (c == _str[i])
					return i;
			}
			return npos;
		}
			int rFind(char c)
			{
				for (int i = _size - 1; i > = 0; --i)
				{
					if (c == _str[i])
						return i;
				}
				return npos;
			}
			String StrSub(size_t pos, size_t size)
			{
				int len = strlen(_str + pos);
				if (size > len)
					size = len;
				return String(_str + pos, size);
			}
	private:
		friend ostream& operator<<(ostream& _cout, const bit::String& s);
	private:
		char* _str;
		size_t _capacity;
		size_t _size;

		const int String::npos = -1;
	};

}
ostream& bit::operator<< (ostream& _cout, const bit::String& s){
	cout << s._str;
	return _cout;
}
void TestHwangString1() {
	bit::String s1;    
	bit::String s2("hello bit");
	bit::String s3(s2);

	s1 = s3;   
	cout << s1 << endl;   
	cout << s2 << endl;
	cout << s3 << endl;
}

void TestHWangString2() {
	bit::String s1("hello");   
	s1.PushBack(' '); 
	s1.PushBack('b');   
	s1.Append(1, 'i');   
	s1 += 't';   
	cout << s1 << endl;
	cout << s1.Size() << endl;
	cout << s1.Capacity() << endl;

	// 利用迭代器列印string中的元素    
	auto it = s1.Begin();    
	while (it != s1.End())   
	{      
		cout << *it++;   
	}
	cout << endl;

	bit::String s2("hello world!!!");  
	s1.Swap(s2);
	cout << s1 << endl; 
	cout << s2 << endl;
}

void TestHWangString3() {
	bit::String s("hello");   
	cout << s << endl;  
	cout << s.Size() << endl;   
	cout << s.Capacity() << endl;

	s.Resize(10, 'a');   
	cout << s << endl; 
	cout << s.Size() << endl;
	cout << s.Capacity() << endl;

	s.Resize(20);  
	cout << s << endl;    
	cout << s.Size() << endl;   
	cout << s.Capacity() << endl;

	s.Resize(5);
	cout << s << endl;   
	cout << s.Size() << endl;   
	cout << s.Capacity() << endl;

	s.Reserve(50); 
	cout << s << endl;  
	cout << s.Size() << endl; 
	cout << s.Capacity() << endl;
}

int main()
{
	TestHwangString1();
	TestHwangString2();
	TestHwangString3();


}

我們的基本思想是把string換算成我們的c語言字串,先就算出來string類的size大小,然後在根據實際情況完成string類空間容量的分配,超過空間模擬vs或者c++的增容方式重新增容,沒有超過則不用。計算尋找字串中某一個位置,或者修改某一個位置時候,就需要用到c++裡面的operator賦值運算子的過載主要思想也就圍繞這兩點吧,其他的我們一時間想不起來,一個也就這些,string模擬實現相比之下邏輯方面其實不是很繞,稍微想一下主要知道這個介面怎麼用,應該用簡簡單單方法都可以實現的。