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模擬實現相比之下邏輯方面其實不是很繞,稍微想一下主要知道這個介面怎麼用,應該用簡簡單單方法都可以實現的。