那些年我與c++的叫板(一)--string類自實現

引子:我們學習了c++中的string類,那我們能不能像以前數據結構一樣自己實現string類呢?以下是cplusplus下的string類,我們參考參考!

廢話不多說,直接代碼實現:(注意函數之間的復用!)

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
//一般在類外進行靜態區變量賦值
const static size_t npos = -1;
//本string簡單實現,代碼量小,故直接寫在聲明中
namespace bit
{
?? ?class string
?? ?{
?? ?public:
?? ??? ?//采用typedef 讓iterator保持接口的一致性
?? ??? ?//iterator底層是模版template
?? ??? ?typedef char* iterator;
?? ??? ?typedef const char* const_iterator;
?? ??? ?
?? ??? ?iterator begin()
?? ??? ?{
?? ??? ??? ?return _str;
?? ??? ?}
?? ??? ?iterator end()
?? ??? ?{
?? ??? ??? ?return _str + _size;
?? ??? ?}
?? ??? ?const_iterator begin() const
?? ??? ?{
?? ??? ??? ?return _str;
?? ??? ?}
?? ??? ?const_iterator end() const
?? ??? ?{
?? ??? ??? ?return _str + _size;
?? ??? ?}

?? ??? ?//構造函數
?? ??? ?string(const char* str = "")
?? ??? ??? ?:_size(strlen(str))
?? ??? ?{
?? ??? ??? ?_str = new char[_size + 1];//為深拷貝,因為如果淺拷貝的話,共用一塊空間,那結果可想而知
?? ??? ??? ?_capacity = _size;
?? ??? ??? ?strcpy(_str, str);//注意char * strcpy ( char * destination, const char * source );
?? ??? ?}
?? ??? ?//拷貝構造,可以隱式類型賦值
?? ??? ?string(const string& s)
?? ??? ?{
?? ??? ??? ?_str = new char[s._capacity + 1];
?? ??? ??? ?strcpy(_str, s._str);
?? ??? ??? ?_size = s._size;
?? ??? ??? ?_capacity = s._capacity;
?? ??? ?}
?? ??? ?string& operator=(const string& s)
?? ??? ?{
?? ??? ??? ?if (this != &s)//排除等于自身的情況
?? ??? ??? ?{
?? ??? ??? ??? ?char* tmp = new char[s._capacity + 1];
?? ??? ??? ??? ?strcpy(tmp, s._str);
?? ??? ??? ??? ?delete[]_str;//只析構_str上的資源
?? ??? ??? ??? ?_str = tmp;
?? ??? ??? ??? ?_size = s._size;
?? ??? ??? ??? ?_capacity = s._capacity;
?? ??? ??? ?}
?? ??? ??? ?return *this;
?? ??? ?}
?? ??? ?~string()
?? ??? ?{
?? ??? ??? ?delete[]_str;
?? ??? ??? ?_str = nullptr;
?? ??? ??? ?_size = _capacity = 0;
?? ??? ?}
?? ??? ?const char* c_str() const
?? ??? ?{
?? ??? ??? ?return _str;
?? ??? ?}
?? ??? ?size_t size() const
?? ??? ?{
?? ??? ??? ?return _size;
?? ??? ?}
?? ??? ?char& operator[](size_t pos)
?? ??? ?{
?? ??? ??? ?assert(pos < _size);
?? ??? ??? ?return _str[pos];
?? ??? ?}
?? ??? ?const char& operator[](size_t pos) const
?? ??? ?{
?? ??? ??? ?assert(pos < _size);
?? ??? ??? ?return _str[pos];
?? ??? ?}

?? ??? ?void reserve(size_t n)
?? ??? ?{
?? ??? ??? ?if (n > _capacity)
?? ??? ??? ?{
?? ??? ??? ??? ?char* tmp = new char[n + 1];
?? ??? ??? ??? ?strcpy(tmp, _str);
?? ??? ??? ??? ?delete[] _str;

?? ??? ??? ??? ?_str = tmp;
?? ??? ??? ??? ?_capacity = n;
?? ??? ??? ?}
?? ??? ?}
?? ??? ?void insert(size_t pos, char ch)
?? ??? ?{
?? ??? ??? ?assert(pos <= _size);

?? ??? ??? ?if (_size == _capacity)
?? ??? ??? ?{
?? ??? ??? ??? ?size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
?? ??? ??? ??? ?reserve(newcapacity);
?? ??? ??? ?}
?? ??? ??? ?size_t end = _size + 1;
?? ??? ??? ?while (end > pos)
?? ??? ??? ?{
?? ??? ??? ??? ?_str[end] = _str[end - 1];
?? ??? ??? ??? ?--end;
?? ??? ??? ?}
?? ??? ??? ?_str[pos] = ch;
?? ??? ??? ?++_size;
?? ??? ?}
?? ??? ?void insert(size_t pos, const char* str)
?? ??? ?{
?? ??? ??? ?assert(pos <= _size);
?? ??? ??? ?size_t len = strlen(str);
?? ??? ??? ?if (_size + len > _capacity)
?? ??? ??? ?{
?? ??? ??? ??? ?reserve(_size + len);
?? ??? ??? ?}
?? ??? ??? ?size_t end = _size;
?? ??? ??? ?//注意pos=0時,對應的值為size_t類型,要int轉
?? ??? ??? ?while (end > (int)pos)
?? ??? ??? ?{
?? ??? ??? ??? ?_str[end+len] = _str[end];
?? ??? ??? ??? ?--end;
?? ??? ??? ?}

?? ??? ??? ?memcpy(_str + pos, str, len);//void * memcpy ( void * destination, const void * source, size_t num );
?? ??? ??? ?_size += len;
?? ??? ?}
?? ??? ?void push_back(char ch)
?? ??? ?{
?? ??? ??? ?insert(_size, ch);
?? ??? ?}
?? ??? ?void append(const char* str)
?? ??? ?{
?? ??? ??? ?insert(_size, str);
?? ??? ?}
?? ??? ?string& operator+=(char ch)
?? ??? ?{
?? ??? ??? ?push_back(ch);
?? ??? ??? ?return *this;
?? ??? ?}
?? ??? ?string& operator+=(const char* str)
?? ??? ?{
?? ??? ??? ?append(str);
?? ??? ??? ?return *this;
?? ??? ?}
?? ??? ?void erase(size_t pos = 0, size_t len = npos)
?? ??? ?{
?? ??? ??? ?assert(pos < _size);

?? ??? ??? ?// len大于前面字符個數時,有多少刪多少
?? ??? ??? ?if (len >= _size - pos)
?? ??? ??? ?{
?? ??? ??? ??? ?_str[pos] = '\0';
?? ??? ??? ??? ?_size = pos;
?? ??? ??? ?}
?? ??? ??? ?else
?? ??? ??? ?{
?? ??? ??? ??? ?strcpy(_str + pos, _str + pos + len);
?? ??? ??? ??? ?_size -= len;
?? ??? ??? ?}
?? ??? ?}

?? ??? ?size_t find(char ch, size_t pos = 0)
?? ??? ?{
?? ??? ??? ?for (size_t i = pos; i < _size; i++)
?? ??? ??? ?{
?? ??? ??? ??? ?if (_str[i] == ch)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?return i;
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ??? ?return npos;
?? ??? ?}
?? ??? ?size_t find(const char* str, size_t pos = 0)
?? ??? ?{
?? ??? ??? ?char* p = strstr(_str + pos, str);//char * strstr (char * str1, const char * str2 );
?? ??? ??? ?return ?p - _str;
?? ??? ?}
?? ??? ?void swap(string& s)
?? ??? ?{
?? ??? ??? ?std::swap(_str, s._str);
?? ??? ??? ?std::swap(_size, s._size);
?? ??? ??? ?std::swap(_capacity, s._capacity);
?? ??? ?}
?? ??? ?string substr(size_t pos = 0, size_t len = npos)
?? ??? ?{
?? ??? ??? ?// len大于后面剩余字符,有多少取多少
?? ??? ??? ?if (len > _size - pos)
?? ??? ??? ?{
?? ??? ??? ??? ?string sub(_str + pos);
?? ??? ??? ??? ?return sub;
?? ??? ??? ?}
?? ??? ??? ?else
?? ??? ??? ?{
?? ??? ??? ??? ?string sub;
?? ??? ??? ??? ?sub.reserve(len);
?? ??? ??? ??? ?for (size_t i = 0; i < len; i++)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?sub += _str[pos + i];
?? ??? ??? ??? ?}
?? ??? ??? ??? ?return sub;
?? ??? ??? ?}
?? ??? ?}
?? ??? ?bool operator<(const string& s) const
?? ??? ?{
?? ??? ??? ?return strcmp(_str, s._str) < 0;
?? ??? ?}
?? ??? ?bool operator>(const string& s) const
?? ??? ?{
?? ??? ??? ?return !(*this <= s);
?? ??? ?}
?? ??? ?bool operator<=(const string& s) const
?? ??? ?{
?? ??? ??? ?return *this < s || *this == s;
?? ??? ?}
?? ??? ?bool operator>=(const string& s) const
?? ??? ?{
?? ??? ??? ?return !(*this < s);
?? ??? ?}
?? ??? ?bool operator==(const string& s) const
?? ??? ?{
?? ??? ??? ?return strcmp(_str, s._str) == 0;
?? ??? ?}
?? ??? ?bool operator!=(const string& s) const
?? ??? ?{
?? ??? ??? ?return !(*this == s);
?? ??? ?}
?? ??? ?void clear()
?? ??? ?{
?? ??? ??? ?_str[0] = '\0';
?? ??? ??? ?_size = 0;
?? ??? ?}
?? ?private:
?? ??? ?// char _buff[16];
?? ??? ?char* _str;
?? ??? ?size_t _size;
?? ??? ?size_t _capacity;
?? ??? ?const static size_t npos;
?? ?};
?? ?istream& operator>> (istream& is, string& str)
?? ?{
?? ??? ?str.clear();
?? ??? ?char ch = is.get();
?? ??? ?while (ch != ' ' && ch != '\n')
?? ??? ?{
?? ??? ??? ?str += ch;
?? ??? ??? ?ch = is.get();
?? ??? ?}
?? ??? ?return is;
?? ?}
?? ?ostream& operator<< (ostream& os, const string& str)
?? ?{
?? ??? ?for (size_t i = 0; i < str.size(); i++)
?? ??? ?{
?? ??? ??? ?os << str[i];
?? ??? ?}
?? ??? ?return os;
?? ?}
}

長圖形式:

還需大家一起改善!我們共赴山海!~~~~~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/12929.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/12929.shtml
英文地址,請注明出處:http://en.pswp.cn/web/12929.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Nacos+GateWay 搭建微服務架構

文章目錄 1.當前項目架構分析1.請求多個模塊的方式1.請求renren-fast模塊開發環境生產環境 2.請求sunliving-commodity模塊1.使用環境變量資源路徑的方式2.開發環境 dev.env.js3.生產環境 prod.env.js 3.文件上傳請求 sunliving-service模塊1.請求后端接口&#xff08;開發環境…

當服務實例出現故障時,Nacos如何處理?

當服務實例出現故障時&#xff0c;Nacos的應對策略 在微服務架構日益盛行的今天&#xff0c;服務之間的穩定性與可靠性成為了我們架構師們不得不面對的重要課題。尤其是在面對服務實例出現故障時&#xff0c;如何確保整個系統的穩定運行&#xff0c;成為了我們首要考慮的問題。…

匯聚榮科技:拼多多上架商品后需要做頁面推廣嗎?

在電商平臺上&#xff0c;商品的曝光率和銷量往往成正比。那么&#xff0c;當您在拼多多上架了新品&#xff0c;是不是就意味著坐等訂單呢?答案顯然是否定的。商品一旦上架&#xff0c;接下來需要做的就是通過有效的頁面推廣來增加商品的可見度&#xff0c;吸引潛在買家的注意…

在亞馬遜上賣燈具需要什么認證,亞馬遜燈飾產品需要審核與認證嗎

LED燈具在亞馬遜美國站銷售&#xff0c;需要有UL認證或者UL報告、FCC&#xff0c;如果是帶消毒滅菌的燈&#xff0c;需要做EPA&#xff0c;歐洲站&#xff0c;日本站&#xff0c;認證只需要CE和ROHSR認證。 UL認證&#xff1a;本認證主要針對充電器、移動電源、手機電池、燈具…

Rust的NLL特性:讓生命周期管理更靈活

Rust的NLL特性&#xff1a;讓生命周期管理更靈活 Rust語言以其獨特的內存安全和并發性能受到開發者的青睞。而在Rust中&#xff0c;一個關鍵的概念就是“生命周期”。為了進一步優化生命周期的管理和借用檢查&#xff0c;Rust引入了NLL&#xff08;Non-Lexical Lifetime&#…

html基礎(全)

html簡介 目錄 什么是網頁 什么是 HTML 常用瀏覽器 WebE標準的構成 基本語法概述 第一個HTML頁面 文檔類型聲明標簽 lang 語言種類 字符集 標題標簽 段落和換行標簽 文本格式化標簽 div和span標簽 圖像標簽和路徑 超鏈接標簽 表格的主要作用 表頭單元格標簽 列…

純血鴻蒙APP實戰開發——Web獲取相機拍照圖片案例

介紹 本示例介紹如何在HTML頁面中拉起原生相機進行拍照&#xff0c;并獲取返回的圖片。 效果預覽圖 使用說明 點擊HTML頁面中的選擇文件按鈕&#xff0c;拉起原生相機進行拍照。完成拍照后&#xff0c;將圖片在HTML的img標簽中顯示。 實現思路 添加Web組件&#xff0c;設置…

【SpringBoot】SpringBoot整合jasypt進行重要數據加密

&#x1f4dd;個人主頁&#xff1a;哈__ 期待您的關注 目錄 &#x1f4d5;jasypt簡介 &#x1f525;SpringBoot使用jasypt &#x1f4c2;創建我需要的數據庫文件 &#x1f4d5;引入依賴 &#x1f513;配置數據庫文件&#xff08;先不進行加密&#xff09; &#x1f319;創…

Anaconda安裝-超詳細版(2024)

掃盲&#xff1a;先裝Python還是先裝anaconda? 安裝anaconda即可&#xff0c;不需要單獨裝python anaconda 是一個python的發行版&#xff0c;包括了python和很多常見的軟件庫, 和一個包管理器conda。 一、下載Anaconda 安裝包&#xff08;官網和國內鏡像資源&#xff09; …

【深度學習】SDXL中的Offset Noise,Diffusion with Offset Noise,帶偏移噪聲的擴散

https://www.crosslabs.org//blog/diffusion-with-offset-noise 帶有偏移噪聲的擴散 針對修改后的噪聲進行微調&#xff0c;使得穩定擴散能夠輕松生成非常暗或非常亮的圖像。 作者&#xff1a;尼古拉斯古藤伯格 | 2023年1月30日 馬里奧兄弟使用穩定擴散挖掘隧道。左圖顯示了未…

Springboot+Vue項目-基于Java+MySQL的高校專業實習管理系統(附源碼+演示視頻+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感謝您閱讀本文&#xff0c;歡迎一鍵三連哦。 &#x1f49e;當前專欄&#xff1a;Java畢業設計 精彩專欄推薦&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python畢業設計 &…

Linux文件:重定向底層實現原理(輸入重定向、輸出重定向、追加重定向)

Linux文件&#xff1a;重定向底層實現原理&#xff08;輸入重定向、輸出重定向、追加重定向&#xff09; 前言一、文件描述符fd的分配規則二、輸出重定向&#xff08;>&#xff09;三、輸出重定向底層實現原理四、追加重定向&#xff08;>>&#xff09;五、輸入重定向…

關于 vs2019 c++20 規范里的 STL 庫里模板 decay_t<T>

&#xff08;1&#xff09; 這個模板&#xff0c;在庫代碼里非常常見。 decay 英文是“衰弱&#xff0c;消減” 的意思&#xff0c;大概能感覺到就是要簡化模板參數 T 的類型&#xff0c;去掉其上的修飾符。因為常用且復雜&#xff0c;故單獨列出其源碼和注釋。先舉例其應用場景…

LINQ(五) ——使用LINQ進行匿名對象初始化

總目錄 C# 語法總目錄 上一篇&#xff1a;LINQ(四) ——使用LINQ進行對象類型初始化 LINQ 五 ——使用LINQ進行匿名對象初始化 6.2 匿名類型 6.2 匿名類型 可以不用聲明定義一個對象&#xff0c;直接使用new&#xff0c;然后直接賦值即可 string[] names { "Tom",…

動態順序表實現

目錄 1. 順序表的概念 2. 實現的功能 3. 順序表的定義 4.順序表的實現 4.1 seqlist.c 4.2 seqlist.h 4.3 test.c 5. 順序表的優缺點 5.1優點 5.2缺點 1. 順序表的概念 用一段物理地址連續的內存依次存儲數據元素的線性結構 本質就是數組&#xff0c;在數組基礎上要求…

從零手寫實現 tomcat-11-filter 過濾器

創作緣由 平時使用 tomcat 等 web 服務器不可謂不多&#xff0c;但是一直一知半解。 于是想著自己實現一個簡單版本&#xff0c;學習一下 tomcat 的精髓。 系列教程 從零手寫實現 apache Tomcat-01-入門介紹 從零手寫實現 apache Tomcat-02-web.xml 入門詳細介紹 從零手寫…

基于Springboot的學生心理壓力咨詢評判(有報告)。Javaee項目,springboot項目。

演示視頻&#xff1a; 基于Springboot的學生心理壓力咨詢評判&#xff08;有報告&#xff09;。Javaee項目&#xff0c;springboot項目。 項目介紹&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三層體系…

Yalmip使用教程(8)-常見報錯及調試方法

博客中所有內容均來源于自己學習過程中積累的經驗以及對yalmip官方文檔的翻譯&#xff1a;https://yalmip.github.io/tutorials/ 這篇博客將詳細介紹使用yalmip工具箱編程過程中的常見錯誤和相應的解決辦法。 1.optimize的輸出參數 眾所周知&#xff0c;optimize是yalmip用來求…

5.7日學習記錄及相關問題解答

1. 閱讀文章 復習 JAVA基礎——接口&#xff08;全網最詳細教程&#xff09; Java之對象的多態性&#xff08;使用生活中通俗的例子講解&#xff09; 新學 JavaWeb——Servlet&#xff08;全網最詳細教程包括Servlet源碼分析&#xff09; 有用 創建Dynamic Web Project工程&…