C++第十九彈---string模擬實現(下)

?個人主頁:?熬夜學編程的小林

💗系列專欄:?【C語言詳解】?【數據結構詳解】【C++詳解】

目錄

1、修改操作

2、迭代器操作

3、字符串操作?

4、非成員函數重載操作

總結


1、修改操作

1、string& operator+= (const char* s);

//尾部插入字符串s
2、string& operator+= (char c);

//尾部插入字符c
3、void push_back (char c);

//尾部插入字符c
4、string& append (const char* s);

//尾部插入(追加)字符串s
5、void insert(size_t pos, char ch);

//在pos位置插入字符c
6、void insert(size_t pos, const char* str);

//在pos位置插入字符串str
7、void erase(size_t pos, size_t len = npos);

//從pos位置刪除n個字符
8、void swap(string& s);

//把字符串數據進行交換

void push_back(char c)
{// 擴容 容量為0則固定為4 其他則*2if (_size == _capacity){reserve(_capacity == 0 ? 4 : 2 * _capacity);}_str[_size] = c;//_size下標插入字符c++_size;//將大小+1_str[_size] = '\0';//字符串最后位置給標志結束的\0
}
void append(const char* s)
{//追加字符串首先得判斷空間是否足夠size_t len = strlen(s);if (len > _capacity - _size)//空間不夠則擴容{reserve(_size + len);//大小為原大小+插入字符串長度}strcpy(_str + _size, s);//將要追加的數據拷貝到原數據尾_size += len;//更新字符串大小
}
string& operator+=(char c)
{push_back(c);//調用尾插字符函數return *this;
}
string& operator+=(const char* str)
{append(str);return *this;
}
void insert(size_t pos, char ch)
{assert(pos <= _size);//斷言,小于字符串大小才能進行插入操作// 擴容if (_size == _capacity){reserve(_capacity == 0 ? 4 : 2 * _capacity);}// end=_size會有無符號與有符號比較問題,因為pos恒大于等于0,end回到-1// 無符號與有符號比較 會提升至無符號比較 即end = -1 還會大于possize_t end = _size + 1;while (end > pos)//end==pos則循環停止{_str[end] = _str[end - 1];//將前面的元素往后面一個位置移動--end;}_str[pos] = ch;//pos位置賦值字符ch++_size;//更新大小
}void insert(size_t pos, const char* str)
{assert(pos <= _size);//pos小于字符串大小才能進行插入操作size_t len = strlen(str);if (len > _capacity - _size)//容量不夠則擴容{reserve(_size + len);}size_t end = _size + len;while (end > pos + len - 1){_str[end] = _str[end - len];//將原數據向后移動len位置--end;}strncpy(_str + pos, str, len);//不需要拷貝\0因此使用strncpy拷貝len長度到原串_size += len;//更新大小
}
void erase(size_t pos, size_t len = npos)
{assert(pos < _size);if (len == npos || len >= _size - pos)//長度為npos或者大于等于字符串大小-pos即刪除整個字符串{_str[pos] = '\0';//直接在pos位置給\0即可_size = pos;//pos為\0下標,剛還為字符串大小}else//將pos+len位置后的數據拷貝到pos為止{strcpy(_str + pos, _str + pos + len);_size -= len;//更新長度}
}
void swap(string& s)//交換類的成員變量即可,
{std::swap(_str, s._str);//調用庫函數的swap模板函數std::swap(_size, s._size);std::swap(_capacity, s._capacity);
}

2、迭代器操作

注意:暫時我們理解的迭代器實質為指針,但不完全是指針,此處就通過指針來模擬實現。

typedef char* iterator;//將迭代器定義成char*類型
typedef const char* const_iterator;將迭代器定義成const char*類型


1、const char* begin() const;

//獲取指向首元素的const迭代器
2、const char* end() const;

//獲取指向尾元素的const迭代器
3、char* begin();

//獲取指向首元素的迭代器
4、char* end();

//獲取指向尾元素的迭代器

typedef char* iterator;
typedef const char* const_iterator;const char* begin() const
{return (const char*)_str;//返回首元素地址,const修飾因此強轉類型
}
const char* end() const
{return (const char*)_str + _size;//尾元素下一個位置地址,即\0位置地址
}
char* begin()
{return _str;
}
char* end()
{return _str + _size;
}

3、字符串操作?

1、const char* c_str() const;

//獲取C字符串首元素地址

2、size_t find(char ch, size_t pos = 0) const;

//從pos位置(默認從0位置)找字符ch,找到則返回下標,否則返回npos
3、size_t find(const char* sub, size_t pos = 0) const;

//從字符串sub的pos位置找是否有匹配的字符串,找到則返回第一個元素下標,否則返回npos
4、string substr(size_t pos = 0, size_t len = npos);

//從pos位置截取len長度(默認截取整個字符串)的子串

const char* c_str() const
{return _str;//返回首地址
}
size_t find(char ch, size_t pos = 0) const
{assert(pos < _size);//小于字符串大小才能進行查找for (size_t i = 0; i < _size; i++)//遍歷字符串{if (_str[i] == ch)return i;//找到字符則返回下標}return npos;
}
size_t find(const char* sub, size_t pos = 0) const
{assert(pos < _size);const char* p = strstr(sub + pos, _str);//從sub+pos位置找,調用C語言庫的找子串函數,找到則返回該值的地址,否則返回NULLif (p)//不為空則返回下標,指針相減即為相差個數,即下標{return p - _str;}else//為空返回npos{return npos;}
}
string substr(size_t pos = 0, size_t len = npos)
{assert(pos < _size);string sub;if (len >= _size - pos)//長度大于_size-pos即將整個字符串截取,也包括len==npos{for (size_t i = pos; i < _size; i++){sub += _str[i];//追加給sub}}else//否則截取len長度{for (size_t i = pos; i < len + pos; i++){sub += _str[i];}}return sub;
}

4、非成員函數重載操作

1、void swap(string& s1, string& s2);

//將類s1數據與類s2數據交換
2、bool operator==(const string& s1, const string& s2);

//比較s1與s2是否相等
3、bool operator<(const string& s1, const string& s2);

//比較s1是否小于s2
4、ostream& operator<<(ostream& out, const string& s);

//流插入,即打印字符串s
5、istream& operator>>(istream& in, string& s);

//流提取,即將輸入的內容給s
6、istream& getline(istream& in, string& s);

//獲取一行信息,即將輸入中回車之前的信息給s

void swap(string& s1, string& s2)
{s1.swap(s2);//調用類成員交換函數,跟庫函數中交換函數重載,先調用類成員函數
}
bool operator==(const string& s1, const string& s2)
{int ret = strcmp(s1.c_str(), s2.c_str());//調用C語言比較字符串函數,等于0則相等return ret == 0;
}
bool operator<(const string& s1, const string& s2)
{int ret = strcmp(s1.c_str(), s2.c_str());return ret < 0;
}ostream& operator<<(ostream& out, const string& s)
{for (auto ch : s){out << ch;//用范圍for變量類}return out;
}istream& operator>>(istream& in, string& s)
{s.clear();//清空串schar ch = in.get();//C++庫中輸入函數,讀取一個字符給chchar buff[128];//先開辟一個128字節空間,減少頻繁擴容size_t i = 0;while (ch != '\n' && ch != ' ')//流提取不識別空格回車{buff[i++] = ch;//將字符賦值給buff數組if (i == 127)//字符串滿了則追加給串s{buff[127] = '\0';//末尾追加標志符\0s += buff;i = 0;//再重新賦值字符給buff數組}ch = in.get();}if (i > 0)//i>0則再追加數據給s{buff[i] = '\0';s += buff;}return in;
}
istream& getline(istream& in, string& s)
{s.clear();char ch = in.get();char buff[128];size_t i = 0;while (ch != '\n')//不識別回車,其他原理同流插入{buff[i++] = ch;if (i == 127){buff[127] = '\0';s += buff;i = 0;}ch = in.get();}if (i > 0){buff[i] = '\0';s += buff;}return in;
}

總結


本篇博客就結束啦,謝謝大家的觀看,如果公主少年們有好的建議可以留言喔,謝謝大家啦!

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

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

相關文章

【Text2SQL 論文】SeaD:使用 Schema-aware 去噪訓練的 end2end 的 Text2SQL

論文&#xff1a;SeaD: End-to-end Text-to-SQL Generation with Schema-aware Denoising ?? NAACL 2022, arXiv:2105.07911 本論文提出 SeaD 模型&#xff0c;使用 schema-aware 的去噪方法來訓練一個 end2end、seq2seq 的 Transformer 模型來實現 Text2SQL。 一、論文速讀…

C++系列-static成員

&#x1f308;個人主頁&#xff1a;羽晨同學 &#x1f4ab;個人格言:“成為自己未來的主人~” 概念 聲明為static的類成員稱為類的靜態成員&#xff0c;用static修飾的成員變量&#xff0c;稱之為靜態成員變量&#xff0c;用static修飾的成員函數&#xff0c;稱之為靜態成…

stm32學習-流水燈

接線 注意&#xff1a;LED燈長一點的引腳是正極。 配置GPIO 1.使用RCC開啟GPIO時鐘 void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); void RCC_APB1Perip…

Stanford斯坦福 CS 224R: 深度強化學習 (2)

實用深度強化學習實現技術 強化學習(RL)是一種通過智能體與環境交互來學習最優決策的機器學習范式。而深度強化學習(DRL)則將深度學習技術引入RL領域,利用深度神經網絡強大的函數擬合能力來處理高維觀察空間,取得了顯著的成功。本章我們將重點介紹一種經典的DRL算法:Q-Learnin…

【Qt 學習筆記】Qt窗口 | 菜單欄 | QMenuBar的使用及說明

博客主頁&#xff1a;Duck Bro 博客主頁系列專欄&#xff1a;Qt 專欄關注博主&#xff0c;后期持續更新系列文章如果有錯誤感謝請大家批評指出&#xff0c;及時修改感謝大家點贊&#x1f44d;收藏?評論? Qt窗口 | 菜單欄 | QMenuBar的使用及說明 文章編號&#xff1a;Qt 學習…

第20屆文博會:“特別呈現”—周瑛瑾雷米·艾融雙個展,著名美術評論家,批評家彭德教授對周瑛瑾作品進行評論

周瑛瑾不是學院派藝術家&#xff0c;但在彩墨畫領域的天賦超出中國八大美院的同類型畫家。相比具有批判意識的當代藝術&#xff0c;他的彩墨藝術如同我們這個苦難世界的創可貼和安慰劑。當我面對他的彩墨畫&#xff0c;首先是驚艷&#xff0c;隨之想到屈原的離騷&#xff0c;還…

無源相控陣雷達

什么是無源相控陣雷達 無源相控陣雷達&#xff08;Passive Electronically Scanned Array Radar&#xff0c;簡稱PESA雷達&#xff09;是一種雷達系統。這里的“無源”并未指其不發射信號&#xff0c;而是指其陣列單元不會產生并發射信號&#xff0c;其特點在于天線表面的陣列…

Vue與React、Angular的比較

Vue、React和Angular是前端開發中三個流行的JavaScript框架&#xff0c;它們各自具有不同的特點、優勢和適用場景。以下是對這三個框架的比較&#xff1a; 1. 基本概念 Vue&#xff1a;Vue是一套用于構建用戶界面的漸進式框架&#xff0c;其核心庫專注于視圖層&#xff0c;易…

[CISCN 2024] Crypto部分復現

文章目錄 OvOez_rsacheckin淺記一下 遲來的文章 OvO 題目描述&#xff1a; from Crypto.Util.number import * from secret import flagnbits 512 p getPrime(nbits) q getPrime(nbits) n p * q phi (p-1) * (q-1) while True:kk getPrime(128)rr kk 2e 65537 kk …

【三維修復、分割與編輯】InFusion、Bootstrap 3D、GaussianGrouping、GaussianEditor等(論文總結)

提示&#xff1a; 文章目錄 前言一、InFusion&#xff1a;擴散模型助力&#xff0c;效率提高20倍&#xff01;(2024)1. 摘要2. 算法3. 效果 二、2D Gaussian Splatting三、Bootstrap 3D:從擴散模型引導三維重建1.摘要2.相關工作3.方法1.Boostrapping by Diffusion 通過擴散模型…

學習存儲協議的利器,聊聊tcpdump和Wireshark

數據存儲技術分為多個方面,包括數據持久化、數據映射、數據壓縮和通信協議等等。其中通信協議是數據存儲技術中非常重要的一部分,正是通信協議使得計算節點可以訪問存儲設備。同時,也正是不同的協議讓存儲系統呈現不同的形態。 如下圖所示,通過iSCSI協議,可以將存儲端的存…

使用std::vector<char>作為數據緩沖區分析

文章目錄 0. 引言1. 內存分配分析2. 性能影響3. 性能優化策略4. 實際性能測試5. 優化建議6. 總結額外建議 0. 引言 在 C 網絡編程中&#xff0c;std::vector<char> 常被用作數據緩沖區。與普通數組相比&#xff0c;std::vector 的內存分配在堆上&#xff0c;而非棧上&am…

【JVM實踐與應用】

JVM實踐與應用 1.類加載器(加載、連接、初始化)1.1 類加載要完成的功能1.2 加載類的方式1.3 類加載器1.4 雙親委派模型1.5自定義ClassLoader1.6 破壞雙親委派模型2.1 類連接主要驗證內容2.2 類連接中的解析2.3 類的初始化3.1 類的初始化時機3.2 類的初始化機制和順序3.2 類的卸…

C從零開始實現貪吃蛇大作戰

個人主頁&#xff1a;星紜-CSDN博客 系列文章專欄 : C語言 踏上取經路&#xff0c;比抵達靈山更重要&#xff01;一起努力一起進步&#xff01; 有關Win32API的知識點在上一篇文章&#xff1a; 目錄 一.地圖 1.控制臺基本介紹 2.寬字符 1.本地化 2.類項 3.setlocale函…

解釋Vue中transition的理解

在Vue中&#xff0c;transition組件用于在元素或組件插入、更新或移除時應用過渡效果。Vue 2和Vue 3都提供了transition組件&#xff0c;但兩者之間有一些差異和更新。以下是關于Vue 2和Vue 3中transition組件的理解&#xff1a; Vue 2中的transition 在Vue 2中&#xff0c;t…

Golang 如何使用 gorm 存取帶有 emoji 表情的數據

Golang 如何使用 gorm 存取帶有 emoji 表情的數據 結論&#xff1a;在 mysql 中盡量使用 utf8mb4&#xff0c;不要使用 utf8。db報錯信息&#xff1a;Error 1366 (HY000): Incorrect string value: \\xE6\\x8C\\xA5\\xE7\\xAC\\xA6...根本原因&#xff1a;emoji 4個字節&#x…

MybatisPlus分頁查詢

分頁查詢controller寫法 public PageResult findByList(RequestBody UserDTO userDTO) {// 分頁IPage<User> page new Page(UserDTO.getPageNumber(), UserDTO.getPageSize());// 條件構造器QueryWrapper queryWrapper new QueryWrapper();queryWrapper.eq("user…

【深度學習】第1章

概論: 機器學習是對研究問題進行模型假設,利用計算機從訓練數據中學習得到模型參數,并最終對數據進行預測和分析,其基礎主要是歸納和統計。 深度學習是一種實現機器學習的技術,是機器學習重要的分支。其源于人工神經網絡的研究。深度學習的模型結構是一種含多隱層的神經…

Springboot應用的配置管理

Spring Boot應用的配置管理 在本文中&#xff0c;我們將深入探討Spring Boot的配置文件&#xff08;application.properties/yaml&#xff09;&#xff0c;以及如何在不同環境中管理配置和使用Spring Config Server。此外&#xff0c;我們還將分享一些高級配置技巧&#xff0c…

Spring Cloud Alibaba 架構-Sentinel整合nacos和gateway

官網地址 sentinel官網: https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E9%A1%B5 sentinel 下載地址: https://github.com/alibaba/Sentinel/releases nacos官網: https://nacos.io/zh-cn/docs/deployment.html nacos下載地址: https://github.com/alibaba/nacos/releas…