C++string类

目录

一、为什么学习string

二、标准库中的string类

2.1 string类的简介

2.2 成员类型

2.3 成员函数

2.3.1 构造、析构与运算符重载      

2.3.2 迭代器

2.3.3 容量

2.3.4 元素的存取        

2.3.5 修改

2.3.6 字符串操作

2.4 成员常量

2.5 非成员函数重载

三、string编程题练习

1. 仅仅反转字母        

2. 字符串最后一个单词的长度

3. 字符串相加        

4. 验证回文串

四、string类的模拟实现



一、为什么学习string

        string的诞生略早于STL(STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架),与STL里面的vector、list相比存在一些不成熟的地方。string与STL里面的vector、list具有相似之处,但是string是被包含在标准库中的。在接下来的学习过程中,我们务必需要阅读一些文档,可能需要一点点英语的基础(尽量不去使用翻译,因为翻译不一定能精确地表达出原意,理解的些许偏差可能对你的学习产生不好的影响,遇到陌生的单词搜索一下它的中文意思即可)

string - C++ Reference (cplusplus.com)https://legacy.cplusplus.com/reference/string/string/?kw=string        C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP(面向对象编程)的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。学习string可以更好地对字符串整体进行操作,而不是像C语言那样对字符串的字符进行操作。


二、标准库中的string类

注意:2.1 ~ 2.5 中并不会详细介绍每一个函数,仅介绍部分常用函数的常规用法(并且以代码运行的截图搭配文字说明展现出来),具体的内容请以文档为准,希望大家能够通过阅读文档学到需要的知识并提升自己相应的能力

2.1 string类的简介

        

2.2 成员类型

        

2.3 成员函数

2.3.1 构造、析构与运算符重载      

        

        

2.3.2 迭代器

        

        

        

        

2.3.3 容量

        

        

        

        

         

2.3.4 元素的存取        

        

2.3.5 修改

        

        

        

2.3.6 字符串操作

        

        

2.4 成员常量

        

2.5 非成员函数重载

        

        string设计了近百个函数,相对有些冗余,学习的时候掌握一些常用的函数(你在学习或者刷题的时候经常遇到的),其它的在需要的时候查看文档即可


三、string编程题练习

1. 仅仅反转字母        

917. 仅仅反转字母 - 力扣(LeetCode)        

给你一个字符串 s ,根据下述规则反转字符串:

  • 所有非英文字母保留在原有位置。
  • 所有英文字母(小写或大写)位置反转。

返回反转后的 s 。

class Solution {
public:bool isLetter(char ch){if((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))return true;elsereturn false;}// 注意isalpha()用于判断字符而不是字母string reverseOnlyLetters(string s) {int begin = 0, end = s.size() - 1;while(begin < end){// 注意:缺少判断条件 begin < end 会出现问题while(begin < end && !isLetter(s[begin])){begin++;}while(begin < end && !isLetter(s[end])){end--;}swap(s[begin], s[end]);begin++, end--;    // }return s;}
};

2. 字符串最后一个单词的长度

字符串最后一个单词的长度_牛客题霸_牛客网 (nowcoder.com)        

描述

计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾)

输入描述:

输入一行,代表要计算的字符串,非空,长度小于5000。

输出描述:

输出一个整数,表示输入字符串最后一个单词的长度。

#include <iostream>
#include <string>
using namespace std;int main() {string str = "";// cin >> str;// cin 默认 空格&换行 终止读取// 使用 getline() 控制读取的结束条件getline(cin, str);size_t i = str.rfind(' ');if(i != string::npos){cout << str.size() - (i+1) << endl;}else {cout << str.size() << endl;}return 0;
}//我们也可以利用cin 默认 空格&换行 终止读取 写出更简约的代码int main()
{string str = "";while(cin >> str){}cout << str.size();
}

3. 字符串相加        

415. 字符串相加 - 力扣(LeetCode)        

给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。

你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。

class Solution {
public:string addStrings(string num1, string num2) {string ans = "";int end1 = num1.size()-1, end2 = num2.size()-1;int next = 0; // 进位// 注意:while(end1 >= 0 && end2 >= 0) 无法处理连续进位的情况(999999+11)while(end1 >= 0 || end2 >= 0){int x1 = end1 >= 0 ? num1[end1] - '0' : 0;int x2 = end2 >= 0 ? num2[end2] - '0' : 0;int ret = x1 + x2 + next;next = ret / 10;ret %= 10;ans += (ret + '0');end1--, end2--;}if(next == 1) ans += '1';reverse(ans.begin(), ans.end());return ans;}
};
// 效率:尾插 + 逆置 > 头插

4. 验证回文串

125. 验证回文串 - 力扣(LeetCode)        

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。

字母和数字都属于字母数字字符。

给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 

class Solution {
public:bool isPalindrome(string s){string s1;auto it = s.begin();while (it != s.end()){if (*it >= 'A' && *it <= 'Z')s1 += (*it + 32);if (*it >= 'a' && *it <= 'z')s1 += *it;if(*it >= '0' && *it <= '9')s1 += *it;++it;}cout << s1 << endl;string rs1;auto rit = s1.rbegin();while (rit != s1.rend()){rs1 += *rit;++rit;}cout << rs1 << endl;if (s1 == rs1)return true;return false;}
};

        


四、string类的模拟实现

注意:本文string类的模拟实现并不够专业标准,仅供初学者连续参考   

#pragma once
#include<iostream>
#include<assert.h>
using namespace std;namespace mystring
{class string{public: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)), _capacity(_size){_str = new char[_capacity + 1];strcpy(_str, str);}/*string(const string& s){_str = new char[s._capacity + 1];strcpy(_str, s._str);_size = s._size;_capacity = s._capacity;}*/void swap(string& s){std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}// 拷贝构造string(const string& s):_str(nullptr), _size(0), _capacity(0){string tmp(s._str);swap(tmp);}// operator=/*string& operator=(const string& s){if (&s != this){char* tmp = new char[s._capacity + 1];strcpy(tmp, s._str);delete[] _str;_str = tmp;_size = s._size;_capacity = s._capacity;}return *this;}*//*string& operator=(const string& s){if (this != &s){string tmp(s);//this->swap(tmp);swap(tmp);}return *this;}*/string& operator=(string tmp){swap(tmp);return *this;}~string(){delete[] _str;_str = nullptr;_size = _capacity = 0;}char& operator[](size_t pos){assert(pos < _size);return _str[pos];}const char& operator[](size_t pos) const{assert(pos < _size);return _str[pos];}size_t capacity() const{return _capacity;}size_t size() const{return _size;}const char* c_str() const{return _str;}void clear(){_str[0] = '\0';_size = 0;}bool empty()const{return _str == nullptr;}void reserve(size_t n){if (n > _capacity){char* tmp = new char[n + 1];strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = n;}}void resize(size_t n, char ch = '\0') {if (n < _size) {_str[n] = '\0';_size = n;}else {if (n > _capacity) {reserve(n);}for (size_t i = _size; i < n; i++) {_str[i] = ch;}_str[n] = '\0';_size = n;}}void push_back(char ch){if (_size == _capacity){reserve(_capacity == 0 ? 4 : _capacity * 2);}_str[_size++] = ch;_str[_size] = '\0';}void append(const char* str){size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}strcpy(_str + _size, str);_size += len;}string& operator+=(char ch){push_back(ch);return *this;}string& operator+=(const char* str){append(str);return *this;}// insert(0, 'x')void insert(size_t pos, char ch){assert(pos <= _size);if (_size == _capacity){reserve(_capacity == 0 ? 4 : _capacity * 2);}// 类型提升会导致 -1 > 0//size_t end = _size;//while (end >= pos)		//{//	_str[end + 1] = _str[end];//	--end;//}		/*//方案一int end = _size;while (end >= (int)pos)		{_str[end + 1] = _str[end];--end;}*/// 方案二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);}int end = _size;while (end >= (int)pos){_str[end + len] = _str[end];--end;}strncpy(_str + pos, str, len);_size += len;}string& insert_s(size_t pos, char ch){assert(pos <= _size);if (_size == _capacity){reserve(_capacity == 0 ? 4 : _capacity * 2);}char* end = _str + _size;while (end >= _str + pos){*(end + 1) = *end;--end;}_str[pos] = ch;_size++;return *this;}string& insert_s(size_t pos, const char* str){assert(pos <= _size);size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}char* end = _str + _size;while (end >= _str + pos){*(end + len) = *end;--end;}strncpy(_str + pos, str, len);_size += len;return *this;}void erase(size_t pos, size_t len = npos){assert(pos <= _size);if (len == npos || pos + len >= _size){_str[pos] = '\0';_size = pos;}else{size_t begin = pos + len;while (begin <= _size){_str[pos] = _str[begin];pos++, begin++;}_size -= len;}}string& erase_s(size_t pos, size_t len = npos){assert(pos < _size);size_t left = _size - pos;if (len >= left){_str[pos] = '\0';_size = pos;}else{strcpy(_str + pos, _str + pos + len);_size -= len;}return *this;}bool operator<(const string& s) const{return strcmp(_str, s._str) < 0;}bool operator==(const string& s) const{return strcmp(_str, s._str) == 0;}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 !(*this < s);}bool operator!=(const string& s) const{return !(*this == s);}// 返回字符ch在string中第一次出现的位置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;}// 返回子串s在string中第一次出现的位置size_t find(const char* s, size_t pos = 0){const char* ret = strstr(_str + pos, s);if (ret == nullptr){return npos;}else{return ret - _str;}}string substr(size_t pos, size_t len = npos){string s;size_t end = pos + len;if (len == npos || pos + len >= _size){len = _size - len;end = _size;}s.reserve(len);for (size_t i = pos; i < pos + len; i++){s += _str[i];}return s;}private:char* _str;size_t _size;size_t _capacity;//static size_t npos;public:const static size_t npos;//const static size_t npos = -1;	// 特例(static 修饰的变量不能在此处初始化)};									    // const static 修饰的整型变量除外//size_t string::npos = -1;const  size_t string::npos = -1;ostream& operator<<(ostream& out, const string& s){for (auto ch : s)out << ch;return out;}istream& operator>>(istream& in, string& s){s.clear();char buff[129];size_t i = 0;char ch;ch = in.get();while (ch != ' ' && ch != '\n'){buff[i++] = ch;if (i == 128){buff[i] = '\0';s += buff;i = 0;}ch = in.get();}if (i != 0){buff[i] = '\0';s += buff;}return in;}
}

        


        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/107645.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【韩顺平 零基础30天学会Java】数组、排序和查找(2days)

数组、排序、查找和多维数组 数组可以存放多个同一类型的数据。数组也是一种数据类 型&#xff0c;是引用数据类型。 定义一个数组 double[] hens {3,5,1,3.4,2,50} 遍历数组得到数组所有元素的和 hens[下标]&#xff0c;下标是从0开始编号的。 可以通过数组名.lenght得到数组…

azure data studio SQL扩展插件开发笔记

node.js环境下拉取脚手架 npm install -g yo generator-azuredatastudio yo azuredatastudio 改代码 运行 调试扩展&#xff0c;在visual studio code中安装插件即可 然后visual studio code打开进行修改运行即可 image.png 运行后自动打开auzre data studio了&#xff0c; 下面…

如何使用CSS实现一个平滑滚动到页面顶部的效果(回到顶部按钮)?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 平滑滚动到页面顶部的效果&#xff08;回到顶部按钮&#xff09;⭐ 创建HTML结构⭐ 编写CSS样式⭐ 编写JavaScript函数⭐ 添加滚动事件监听器⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右…

HBase--技术文档--基本概念--《快速扫盲》

官网 Apache HBase – Apache HBase™ Home 阿里云hbase 云数据库HBase_大数据存储_订单风控_数据库-阿里云 云数据库 HBase-阿里云帮助中心 基本概念 HBase是一种分布式、可扩展、支持海量数据存储的NoSQL数据库。它基于Hadoop&#xff0c;采用列式存储方式&#xff0c;可…

TCP协议的重点知识点

TCP协议的重点知识点 TCP(传输控制协议)是一种面向连接、可靠的数据传输协议,工作在传输层,提供可靠的字节流服务。它是互联网协议栈中最重要、最复杂的协议之一,也是面试中常被问到的知识点。本文将详细介绍TCP协议的各个重要概念。 TCP基本特性 TCP主要具有以下基本特性: …

【面试题】前端面试复习6---性能优化

前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 性能优化 一、性能指标 要在 Chrome 中查看性能指标&#xff0c;可以按照以下步骤操作&#xff1a; 打开 Chrome 浏览器&#xff0c;并访问你想要测试…

4G显存即可使用SDXL:离线、开源、免费#Fooocus初体验

Midjourney CEO | David Holz, 2019 &#xff1a; 用户可以忘记所有这些复杂的技术参数&#xff0c;只享受人与计算机之间的交互&#xff0c;“探索新的思维媒介&#xff0c;扩展人类的想象力” Fooocus 用开源和离线的方式挑战 Midjourney。Fooocus 是一款开源的图像生成项目…

视频汇聚平台EasyCVR安防视频监控平台新增经纬度选取功能的详细介绍

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录像、…

【CSS】定位 ( 子元素绝对定位 父元素相对定位 | 代码示例 )

一、子元素绝对定位 父元素相对定位 绝对定位 要和 带有定位 的 父容器 搭配使用 ; 子元素 使用绝对定位 , 父元素要使用 相对定位 ; 子元素使用 绝对定位 , 在布局中不会保留其位置 , 子元素完全依赖 父容器 的位置 , 此时就要求父容器必须稳定 , 如果父容器使用了 绝对布…

LLMs多任务指令微调Multi-task instruction fine-tuning

多任务微调是单任务微调的扩展&#xff0c;其中训练数据集包括多个任务的示例输入和输出。在这里&#xff0c;数据集包含指导模型执行各种任务的示例&#xff0c;包括摘要、评论评分、代码翻译和实体识别。 您在这个混合数据集上训练模型&#xff0c;以便它可以同时提高模型在…

c++11 标准模板(STL)(std::basic_ostringstream)(一)

定义于头文件 <sstream> template< class CharT, class Traits std::char_traits<CharT> > class basic_ostringstream;(C11 前)template< class CharT, class Traits std::char_traits<CharT>, class Allocator std::allo…

【黑马头条之热点文章kafkaStream】

本笔记内容为黑马头条项目的热点文章-实时计算部分 目录 一、实时流式计算 1、概念 2、应用场景 3、技术方案选型 二、Kafka Stream 1、概述 2、Kafka Streams的关键概念 3、KStream 4、Kafka Stream入门案例编写 5、SpringBoot集成Kafka Stream 三、app端热点文章…

4.网络设计与redis、memcached、nginx组件(二)

系列文章目录 第四章 网络设计与redis、memcached、nginx组件(一) 第五章 网络设计与redis、memcached、nginx组件(二) 文章目录 系列文章目录[TOC](文章目录) 前言一、reactor模型&#xff1f;二、Reactor 开发1.建立连接 三、典型reactor 模型单reactor 模型典型 readisradi…

37、springboot 为 spring mvc 提供的自动配置及对自动配置的一些自定义定制(大体思路)

springboot 为 spring mvc 提供的自动配置及对自动配置的一些自定义定制&#xff08;大体思路&#xff09; ★ Spring Boot主流支持两个MVC框架&#xff1a; Spring MVC&#xff08;基于Servlet&#xff09; Spring WebFlux&#xff08;基于Reactive&#xff0c;属于响应式AP…

Eduma主题 - 线上教育WordPress主题/网站

Eduma主题 – 线上教育WordPress主题是为教育网站、LMS、培训中心、课程中心、学院、大学、学校、幼儿园而制作的。基于我们使用以前的主题eLearning WP构建WordPress LMS的经验&#xff0c;Education WP是下一代&#xff0c;也是围绕WordPress最好的教育主题之一&#xff0c;它…

一文了解SpringBoot中的Aop

目录 1.什么是Aop 2.相关概念 3.相关注解 4.为什么要用Aop 5.Aop使用案例 1.什么是Aop AOP&#xff1a;Aspect Oriented Programming&#xff0c;面向切面&#xff0c;是Spring三大思想之一&#xff0c;另外两个是 IOC-控制反转 DI-依赖注入 (Autowired、Qualifier、Re…

【Linux操作系统】Linux系统编程中的互斥锁

文章目录 1. 互斥锁的原理2. 互斥锁的相关函数3. 互斥锁的例子总结 1. 互斥锁的原理 在Linux系统编程中&#xff0c;互斥锁&#xff08;Mutex&#xff09;是一种用于保护共享资源的同步机制。它可以确保在任意时刻只有一个线程可以访问被保护的资源&#xff0c;从而避免了多个…

极狐GitLab 价值流管理之「总时间图」使用指南

本文来源&#xff1a;about.gitlab.com 作者&#xff1a;Haim Snir 译者&#xff1a;极狐(GitLab) 市场部内容团队 对于软件研发管理者来说&#xff0c;了解在整个研发过程中时间都耗费在了哪些地方&#xff0c;是进行交付价值优化的关键洞察。GitLab / 极狐GitLab 新的价值流分…

【Flink】Flink架构及组件

我们学习大数据知识的时候&#xff0c;需要知道大数据组件如何安装以及架构组件&#xff0c;这将帮助我们更好的了解大数据组件 对于大数据Flink&#xff0c;架构图图下&#xff1a; 整个架构图有三种关键组件 1、Client&#xff1a;负责作业的提交。调用程序的 main 方法&am…

StreamPark

1、StreamPark的标语 一个神奇的框架&#xff0c;让流处理更简单 2、StreamPark的前世今生 早期用名streamx&#xff0c;加入apache孵化器之后更名为StreamPark 3、StreamPark可以为你提供什么 降低学习成本、开发门槛&#xff0c;让开发者只用关心核心的业务 简单来说&#xf…