經典面試題—string類的詳細分析與實現
阿新 • • 發佈:2019-02-17
#define _CRT_SECURE_NO_WARNINGS -1 #include <new.h> #include <iostream> using namespace std; class String { public: //建構函式 String(const char* str = "") :_str(new char[strlen(str) + 1]) { strcpy(_str, str); _size = strlen(str); _capacity = _size; } ////拷貝建構函式 //String(const String& s)//傳統寫法 // :_str(new char[s._capacity]) //{ // strcpy(_str, s._str); // _size = s._size; // _capacity = s._capacity; //} ////賦值操作符過載 //String& operator=(String s)//傳統寫法 //{ // if (this != &s) // { // char* tmp = new char[strlen(s._str) + 1]; // delete[] _str; // strcpy(_str, s._str); // _size = s._size; // _capacity = s._capacity; // } // return *this; //} // s1.Swap(s2); void Swap(String& s) { char* tmp = _str; _str = s._str; s._str = tmp; } // 拷貝建構函式 // String s2(s1) String(const String& s)//現代寫法 :_str(NULL) { String tmp(s._str); this->Swap(tmp); _size = s._size; _capacity = s._capacity; } //賦值操作符過載 // s1 = s2 String& operator=(String s)//現代寫法 { if (this != &s) { String tmp(s._str); this->Swap(s); _size = s._size; _capacity = s._capacity; } return *this; } //解構函式 ~String() { if (_str != NULL) { delete[] _str; _str = NULL; _size = 0; _capacity = 0; } } //獲取類中的字串成員變數 const char* c_str() { return _str; } //擴容 void Expand(size_t n) { if (n > _capacity) { char* tmp = new char[n + 1]; strcpy(tmp, _str); delete[] _str; _str = tmp; _capacity = n; } } //尾插一個字元 void PushBack(char ch) { if (_size >= _capacity) { Expand(_capacity * 2); } _str[_size++] = ch; _str[_size] = '\0'; } //尾插一個字串 void PushBack(const char* str) { if (str == NULL) { return; } int len = strlen(str); if (_size + len > _capacity) { Expand(_size + len); } strcpy(_str + _size, str); _size += len; } //+操作符過載,+一個字元 String operator+(char ch) { String tmp(*this); tmp.PushBack(ch); return tmp; } //+=操作符過載,+=一個字元 String& operator+=(char ch) { //this->PushBack(ch); PushBack(ch); return *this; } //+操作符過載,+一個字串 String operator+(const char* str) { String tmp(*this); tmp.PushBack(str); return tmp; } //+=操作符過載,+=一個字串 String& operator+=(const char* str) { //this->PushBack(str); PushBack(str); return *this; } //尾刪一個字元 void PopBack() { _str[_size] = '\0'; _size--; } //指定位置插入一個字元 void Insert(size_t pos, char ch) { if (pos > _size)//插入位置不合法 { return; } if (_size >= _capacity)//擴容 { Expand(_capacity * 2); } if (pos == _size) { _str[_size++] = ch; } else { char* tmp = new char[_size - pos + 1]; strcpy(tmp, _str + pos); _str[pos] = ch; strcpy(_str + pos + 1, tmp); _size++; delete[] tmp; } } //指定位置插入一個字串 void Insert(size_t pos, const char* str) { if (pos > _size || str == NULL) { return; } int len = strlen(str); if (_size + len > _capacity)//擴容 { Expand(_size + len); } if (pos == _size) { strcat(_str, str); } else { char* tmp = new char[_size - pos + 1]; strcpy(tmp, _str + pos); strcpy(_str + pos,str); strcpy(_str + pos + len, tmp); ////或直接使用strcat //strcat(_str, tmp); delete[] tmp; } } //刪除pos下標開始往後n個元素 void Erase(size_t pos, size_t n = 1) { if (pos > _size) { return; } char* str = _str + pos; while (*str != '\0' && n > 0) { *str = '\0'; str++; n--; _size--; } strcpy(_str + pos, str); } //查詢字串中的某個字元 size_t Find(char ch) { char* str = _str; while (*str != '\0') { if (*str == ch) { return (int)(str - _str); } str++; } return -1; } //查詢第一個子串的的位置 size_t Find(const char* str) { if (str == NULL) { return -1; } char* tmp = strstr(_str, str); if (tmp != NULL) { return (size_t)(tmp - _str); } return -1; } //更改字串中的某個字元 void Replace(char ch1, char ch2) { char* str = _str; while (*str != '\0') { if (*str == ch1) { *str = ch2; } str++; } } //替換字串中的某個字串 void Replace(const char* sub1, const char* sub2) { if (sub1 == NULL || sub2 == NULL || strcmp(sub1, sub2) == 0) { return; } size_t pos = Find(sub1); if (pos != -1) { char* str = _str; int len = strlen(_str); int len1 = strlen(sub1); int len2 = strlen(sub2); if (len1 == len2) { while (pos != -1) { _str = _str + pos; int i = 0; while (i < len1) { _str[i] = sub2[i]; i++; } pos = Find(sub1); } _str = str; } else { int count = 0; char** arr = new char*[len]; memset(arr, 0, sizeof(char*)*len); while (pos != -1) { _str =_str + pos + 1; arr[count] = _str - 1; count++; pos = Find(sub1); } _str = str; int capacity = len + count*(len2 - len1); char* newStr = new char[capacity + 1]; memset(newStr, 0, capacity + 1); count = 0; char* cur = newStr; while (*_str != '\0') { if (_str == arr[count]) { for (int i = 0; i < len2; i++) { cur[i] = sub2[i]; } _str += len1; cur += len2; count++; } else { *cur++ = *_str++; } } _str = newStr; _size = capacity; _capacity = capacity; newStr = str; delete[] newStr; } } else { return; } } // >操作符過載,比較字串大小 bool operator>(const String& s) { if (this == &s || strcmp(_str, s._str) > 0) { return true; } return false; } // =操作符過載,判斷字串是否相等 bool operator==(const String& s) { if (this == &s || strcmp(_str, s._str) == 0) { return true; } return false; } bool operator>=(const String& s) { if (*this > s && *this == s) { return true; } return false; } bool operator<(const String& s) { if (!(*this >= s)) { return true; } return false; } bool operator<=(const String& s) { if (!(*this > s)) { return true; } return false; } bool operator!=(const String& s) { if (!(*this == s)) { return true; } return false; } private: //char _buffer[16]; char* _str; size_t _size; size_t _capacity; }; int main() { //String s1("abc"); //String s2(s1); //String s3("123abc"); //s3 = s1; //cout << (s3 + 'd').c_str() << endl; //cout << (s3 + 'e').c_str() << endl; //cout << (s3 + 'f').c_str() << endl; //cout << (s3 + 'g').c_str() << endl; //cout << (s3 + 'h').c_str() << endl; //s3 += "123456"; //s3.Insert(1, 'x'); //s3.Insert(2, 'y'); //s3.Insert(3, 'z'); //s3.Insert(1, '0'); //s3.Insert(0, "789"); //cout << s3.Find('a') << endl; //s3.Replace('a', '1'); //cout << s3.Find('a') << endl; //s3.Erase(0, 3); ////string s="abc123abc"; ////s = s.replace("abc", "xx"); //cout << s3.Find('b') << endl; //cout << s3.Find('w') << endl; String s("abc123"); s.Replace("xyz", "asd"); s.Replace("a", "ddd"); s.Replace("123", "f"); s.Replace("dbc", "666"); s.Replace("666", "6"); cout << s.c_str() << endl; system("pause"); return 0; }