【c++】string类 (一)

news2024/11/25 0:30:23

简介

由于c++的历史包袱,c++要兼容c语言,c++的字符串要兼容c语言,在 C++ 中,字符串通常使用两种主要的方式来表示:

  1. C风格字符串(C-style strings)

    • 依然是以 '\0' 结尾的字符数组。这种表示方式与 C 语言中的字符串相同。例如:
      const char* str = "Hello, World!";
    • 在内存中,它是一个字符数组,最后一个字符是空字符 '\0'
  2. C++ 的标准库字符串(std::string

    • C++ 提供了一个 std::string 类型,属于标准库的一部分。它管理自己的内存,并且不需要手动处理 '\0'。使用 std::string 更加方便和安全。例如:
      #include <string> 
      std::string str = "Hello, World!";
    • std::string 处理字符串的长度、内存分配和释放,因此开发者可以专注于字符串的内容,而不必担心细节。

c风格类型的字符串我们都已经很熟悉,\0的存在让我们在处理在处理字符串的时候需要时刻小心,在手动拼接或复制字符串时经常会因为\0处理不妥而出错。c++为我们提供了一个全新的string来处理字符串的长度、内存分配和释放,因此开发者可以专注于字符串的内容,而不必担心细节。

在一切开始之前,我们先介绍一个网站。www.cplusplus.com是一个广受欢迎的C++编程语言资源网站,成立于2000年代初期。开始由一个c++爱好者建立,后来各路大佬汇聚,网站内容也非常成熟,可供我们学习和参考。

string类的常用接口说明

构造函数 

c++98就为我们提供了7个构造函数,当然并不要求也没有必要对所有的函数烂熟于心,大多数时候把这个当成词典来使用就可以了,选常用的一部分学习。

学习类和对象很容易大家就能知道上面哪是重要的 

不传参的默认构造,拷贝构造和第四个用常量字符串初始化的构造。

#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s1;//默认构造
	string s2("123456789");
	string s3(s2);//拷贝构造

	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;

	cin >> s1;
	cout << s1 << endl;
	return 0;
}

我们也可以向里面输入中文

便利string的三种方式

operator[]

string类重载了[],这让我们可以像数组一样访问字符串。

同时注意看,重载后返回的类型是引用,不仅可以减少拷贝,关键在于这样我们能够直接通过下标对字符串进行修改。在重载的时候加入了断言,当pos大于size(越界时),编译器会报错。  

#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s1;
	string s2("123456789");
	string s3(s2);

	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;

	cout << s2[2] << endl;//可以通过下标访问
	s2[0] = '5';//也可以直接修改
	cout << s2 << endl;
	/*cin >> s1;
	cout << s1 << endl;*/
	return 0;
}

遍历string的第一种方法就是:下标 + []


#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s1;
	string s2("123456789");
	string s3(s2);

	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;

	cout << s2[2] << endl;//可以通过下标访问
	s2[0] = '5';//也可以直接修改
	cout << s2 << endl;
	/*cin >> s1;
	cout << s1 << endl;*/


	for (size_t i = 0; i < s2.size(); i++)
	{
		cout << s2[i] << " ";
	}
	cout << endl;
	return 0;
}

迭代器 

迭代器是一种用于遍历容器(如数组、向量、链表等)元素的对象。它提供了一种统一的方法来访问不同类型的容器中的元素(所有的容器都可以由它访问),而无需了解容器的内部结构。

正向迭代器 

begin()返回第一个位置;

end()返回最后一个位置的下一个位置。

for (size_t i = 0; i < s2.size(); i++)
{
	cout << s2[i] << " ";
}
cout << endl;

string::iterator it= s2.begin();
while (it != s2.end())
{
	cout << *it << " ";
	++it;
}
cout << endl;

反向迭代器

反向迭代器提供了一个rbegin()指向最后一个位置

 

rend()指向第一个位置的前一个位置。这里任然要使用++,++被重载了让它能倒着遍历。 

string s1;
string s2("123456789");
string s3(s2);

cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
string::reverse_iterator it = s2.rbegin();
while (it != s2.rend())
{
	cout << *it << " ";
	++it;
}
cout << endl;

const迭代器

由于权限,普通迭代器可读可写,无法访问const对象,const对象要用const迭代器,只读不写。 


	const string s2("hello world!");
	//正向
	string::const_iterator cit = s2.begin();
	while (cit != s2.end())
	{
		cout << *cit << " ";
		++cit;
	}
	cout << endl;
	//反向
	string::const_reverse_iterator rcit = s2.rbegin();
	while (rcit != s2.rend())
	{
		cout << *rcit << " ";
		++rcit;
	}
	cout << endl;

 

 范围for

字符赋值,自动迭代,自动判断结束,底层由迭代器实现。适用于容器和数组。

for (size_t i = 0; i < s2.size(); i++)
{
	cout << s2[i] << " ";
}
cout << endl;

string::iterator it= s2.begin();
while (it != s2.end())
{
	cout << *it << " ";
	++it;
}
cout << endl;

for (auto ch : s2)
{
	cout << ch << " ";
}
cout << endl;

但是由于范围for()是给ch这个局部变量赋值,并不能直接改变s2,而迭代器是直接可以改变s2的。

string::iterator it = s2.begin();
while (it != s2.end())
{
	*it += 2;
	cout << *it << " ";
	++it;
}
cout << endl;

for (auto ch : s2)
{
	ch -= 2;
	cout << ch << " ";
}
cout << endl;

cout << s2 << endl;

 

如果要使用范围for()来改变传入的形参,在传入时加上引用,这样就不会生成拷贝而是直接修改传入的形参。 

capacity

 不同编译器对内存空间的处理是不一样的

string s;
size_t sz = s.capacity();

cout << "original capacity:" << sz << endl;
for (int i = 0; i < 100; i++)
{
	s.push_back('c');
	if (sz != s.capacity())
	{
		sz = s.capacity();
		cout << "capacity changed: " << sz << endl;
	}
}

在vs中有一个buff数组,该开始中string中的数据是储存在buff中的,当要储存的数据空间大于15时才会额外开空间,该开始要把buff中的数据拷贝出来一共开了两倍空间,后边都是开的1.5倍空间。c++只规定了开空间,但是怎么开空间没有做具体的要求。其他的编译器开空间的方式可能会不同。 

频繁的扩容会导致效率低下,为解决这一问题,c++提供了reserve()可以预留空间。

string s("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");

cout << s.size() << endl;
cout << s.capacity() << endl << endl;

s.reserve(10);
cout << s.size() << endl;
cout << s.capacity() << endl << endl;
s.reserve(30);
cout << s.size() << endl;
cout << s.capacity() << endl << endl;
s.reserve(40);
cout << s.size() << endl;
cout << s.capacity() << endl << endl;
s.reserve(50);
cout << s.size() << endl;
cout << s.capacity() << endl << endl;

 但是c++标准并没有规定具体怎么处理空间,不同的编译器也不一样。

仅仅反转字母

 https://leetcode.cn/problems/reverse-only-letters/

题目解析:

题目中让我们仅仅反转字母,首先我们要分类-----字母和非字母;很简单所有的字母并不多,我们只需要筛选出字母就好,写一个函数实现这个功能 。要实现反转首先就要有两个位置,使用双指针,从首尾开始遍历。基本框架已经确定,接下来就是敲定判断的细节了。首先考虑极限条件,输入的没有字母left会一直加,越界了;所以处理left和right时要加上判断条件。

class Solution {
public:
     bool Isletter(char ch)
    {
	     if (ch >= 'a' && ch <= 'z')
	    {
	     	return true;
	    }
	      if (ch >= 'A' && ch <= 'Z')
	     {
	    	return true;
	       }
	return false;
       }
    string reverseOnlyLetters(string s) {
        if (s.empty())
        {
            return s;
        }
        size_t left = 0;
        size_t right = s.size() - 1;
        while(left < right)
        {
            while(left < right && !Isletter(s[left]))
            {
                left++;
            }
            while(left < right && !Isletter(s[right]))
            {
                right--;
            }
            swap(s[left++],s[right--]);
        }
        return s;
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java 并发编程】初识多线程

前言 到目前为止&#xff0c;我们学到的都是有关 “顺序” 编程的知识&#xff0c;即程序中所有事物在任意时刻都只能执行一个步骤。例如&#xff1a;在我们的 main 方法中&#xff0c;都是多个操作以 “从上至下” 的顺序调用方法以至结束的。 虽然 “顺序” 编程能够解决相当…

YOLO11改进|卷积篇|引入SPDConv

目录 一、【SPD】卷积1.1【SPD】卷积介绍1.2【SPD】核心代码 二、添加【SPD】卷积2.1STEP12.2STEP22.3STEP32.4STEP4 三、yaml文件与运行3.1yaml文件3.2运行成功截图 一、【SPD】卷积 1.1【SPD】卷积介绍 SPD-Conv卷积的结构图如下&#xff0c;下面我们简单分析一下其处理过程…

贪心算法.

序幕 贪心算法&#xff08;Greedy Algorithm&#xff09;是一种在求解问题时采取逐步构建解决方案的策略&#xff0c;每一步都选择当前状态下局部最优的解&#xff0c;期望通过局部最优解能够得到全局最优解。 以上为了严谨性&#xff0c;引用了官方用语。 而用大白话总结就是&…

如何移除 iPhone 上的网络锁?本文筛选了一些适合您的工具

您是否对 iPhone 运营商的网络感到困惑&#xff1f;不用担心&#xff0c;我们将向您介绍 8 大免费 iPhone 解锁服务。这些工具可以帮助您移除 iPhone 上的网络锁&#xff0c;并使您能够永久在网络上使用您的设备。如果您想免费解锁 iPhone&#xff0c;请阅读本文并找到最适合您…

APC论文总结

论文详情 论文标题&#xff1a;APC: Adaptive Patch Contrast for Weakly Supervised Semantic Segmentation 论文作者&#xff1a;Wangyu Wu&#xff0c;Tianhong Dai&#xff0c;Zhenhong Chen&#xff0c;Xiaowei Huang&#xff0c;Fei Ma&#xff0c;Jimin Xiao 发表时间…

股票期货高频数据获取方法

导语&#xff1a;在量化交易领域&#xff0c;获取高质量的股票期货高频数据是进行有效分析和策略开发的基础。本文从专业量化角度出发&#xff0c;介绍了几种获取股票期货高频数据的方法。一、使用专业数据供应商1. 【推荐】**银河数据库&#xff08;yinhedata.com&#xff09;…

【Blender Python】6.修改物体模式

概述 Blender对象共有6种编辑模式&#xff0c;物体模式、编辑模式、雕刻模式、顶点绘制、权重绘制和纹理绘制。 在Blender Python中通过bpy.ops.object的mode_set()方法可以修改物体的编辑模式。只需要传入相应的mode参数就行了。 让物体进入编辑模式 >>> bpy.ops.…

leetcode 力扣算法题 快慢指针 双指针 19.删除链表的倒数第n个结点

删除链表的倒数第N个结点 题目要求题目示例解题思路从题目中的已知出发思考寻找目标结点条件转换核心思路 需要注意的点改进建议 完整代码提交结果 题目要求 给你一个链表&#xff0c;删除链表的倒数第n个结点&#xff0c;并且返回链表的头结点。 题目示例 示例 1&#xff1…

libcurl网络协议库使用Demo

目录 1 libcurl简介 2 libcurl编译 3 使用步骤 4 函数说明 4.1 全局初始化函数 curl_global_init 4.2 全局释放函数 curl_global_cleanup 4.3 libcurl库版本 curl_version 4.4 开启会话 curl_easy_init 4.5 结束会话 curl_easy_cleanup 4.6 设置传输选项 curl_easy_se…

最新版快递小程序源码 独立版快递系统 附教程

懂得都懂&#xff0c;现在电商平台退换货量大&#xff0c;快递需求量大&#xff0c;对接物流一个单子4块到6块之间 其中间是例如润 其余的 就不说了吧 互站上买的源码 分享一下 还有个方法赚钱就是 拼多多退货自己邮寄 5块钱 运费自己填写12元 白捡7元美滋滋 源码下载&…

Vivado - JTAG to AXI Master (GPIO、HLS_IP、UART、IIC)

1. 简介 本文分享 JTAG to AXI Master IP Core 的使用教程。 此 IP 用于 AXI 接口向设计输入数据&#xff0c;或者读取数据。通过 Tcl 控制台编写命令来驱动此 IP&#xff0c;通过 JTAG 即可进行操作&#xff0c;而这个 IP 则在 AXI 端口上驱动 AXI 事务。由于这个核心没有自…

面试题之- null和undefined的区别

前言 首先undefined和null都是基本数据类型&#xff0c;这两个基本数据类型分别都只有一个值&#xff0c;就是undefined和null。 undefined代表的含义是未定义&#xff0c;null代表的的含义是空对象&#xff0c;一般变量声明了但是还有没有定义的时候会返回undefined&#xf…

每日学习一个数据结构-默克尔树(Merkle Tree)

文章目录 概述特征构建过程使用场景示例总结 设计目的一、提高数据验证效率二、增强数据安全性三、适用于分布式系统 底层原理一、数据块划分与哈希计算二、二叉树的构建三、默克尔树的应用与优势 更新机制 概述 默克尔树&#xff08;Merkle Tree&#xff09;&#xff0c;也称…

cnn突破六(四层bpnet网络公式)

四层bpnet网络反向传播公式推导&#xff1a; X【196】-》HI【128】/HO【128】-》H2I【60】/H2O【60】-》YI【10】/YO【10】&#xff0c; 期望是d【10】 X&#xff0c;HI之间用w1【196&#xff0c;128】 HO&#xff0c;H2I之间用w12【128,60】 H2O&#xff0c;YI之间用w2【…

Zabbix 企业级应用(Zabbix Enterprise Application)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

【AI学习】Mamba学习(三):离散化SSM的矩阵计算

SSM离散化表示 除了连续的输入之外&#xff0c;还会通常碰到离散的输入(如文本序列)。所以SSM需要离散化形式&#xff0c;就是下面公式2和3。 SSM离散化过程 但是好奇这个离散化过程是如何进行的&#xff1f; 《一文通透想颠覆Transformer的Mamba&#xff1a;从SSM、HiPPO、…

【NIO基础】NIO(非阻塞 I/O)和 IO(传统 I/O)的区别,以及 NIO 的三大组件详解

目录 1、NIO 2、NIO 和 IO 的区别 1. 阻塞 vs 非阻塞 2. 一个线程 vs 多个连接 3. 面向流 vs 面向缓冲 4. 多路复用 3、Channel & Buffer (1&#xff09;Channel&#xff1a;双向通道 (2&#xff09;Buffer&#xff1a;缓冲区 (3&#xff09;ByteBuffer&#xff…

GO网络编程(五):海量用户通信系统3:整体框架与C/S通信总体流程【重要】

这个系统其实是尚硅谷的老韩讲的&#xff08;尚硅谷网络编程项目&#xff09;&#xff0c;但是他讲得很碎片化&#xff0c;思路不够清晰&#xff0c;时间又长&#xff0c;所以要掌握还是挺难的。如果你听了他的视频&#xff0c;不去梳理系统业务流程&#xff0c;不去看代码就往…

云计算身份认证与访问控制(Cloud Computing Identity Authentication and Access Control)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

支持向量机(SVM)基础教程

一、引言 支持向量机&#xff08;Support Vector Machine&#xff0c;简称SVM&#xff09;是一种高效的监督学习算法&#xff0c;广泛应用 于分类和回归分析。SVM以其强大的泛化能力、简洁的数学形式和优秀的分类效果而备受机器学 习领域的青睐。 二、SVM基本原理 2.1 最大间…