字符串C++string容器详解(知识点+相关LeetCode题目)

本文介绍了C++中字符串的常用操作,包括访问、修改、查找、比较和翻转,详细讲解了reverse等函数的用法,并列举了力扣上的经典字符串反转题目,如344和541题,探讨了如何原地修改字符串并保持O(1)的空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

前言

1.1访问字符串内容

1.2修改字符串

1.3查找和比较

1.4 区间翻转

1.5 其他

二、经典力扣题目

2.1 反转字符串 344

2.2 反转字符串II  541

2.2.1 题目和题解

2.2.2 reverse函数用法

2.2.3 迭代器

2.3 反转字符串中的单词 151

2.4 重复的子字符串 459


前言

 string是C++风格的字符串,而string本质是一个类。char* 是一个指针,string是一个类,类内部封装了char* ,管理这个字符串,是一个char*型的容器

一、字符串函数用法

1.1访问字符串内容

  • size(): 返回字符串的长度
  • empty(): 判断字符串是否为空
  • operator[]: 用于访问某个字符,下标从0开始
  • front(): 返回字符串的第一个字符
  • back(): 返回字符串的最后一个字符

1.2修改字符串

append(): 将一个字符串添加到另一个字符串的末尾

insert(): 在指定位置插入一个字符串 || 可用push_back平替 

s.insert(1,1,'');//在索引1位置,插入1一个元素''

clear(): 删除所有字符

append():将目标字符串插入到当前字符串的末尾 || 直接+=亦可

s.append(aimstr);

1.3查找和比较

  • find(str,num):在num的索引位置开始寻找指定字符串 ,存在则返回字符串的第一个字符的位置,不存在则返回-1
  • rfind(): 在字符串中查找指定子串,返回子串最后一次出现的位置
  • find_first_of(): 在字符串中查找给定字符集的第一个匹配字符的位置
  • find_last_of(): 在字符串中查找给定字符集的最后一个匹配字符的位置
  • compare(): 比较两个字符串的大小,返回0表示两个字符串相等

1.4 区间翻转
 

  • reverse(str.begin(),str.end()):反转字符串--(左闭右开)   
  • reverse(vector.begin(),vector.end()) :反转向量
  • reverse(a,a+strlen(a)) :反转数组
  • reverse():数组全部翻转

1.5 其他


substr(): 返回指定位置开始的指定长度的子串

s.substr(start,singleCount);

swap(): / swap(x1,x2):可以实现交换容器中的元素,当然也可以进行容器间的互换(互换所有元素)

使用vector<char> s也可以实现字符串的效果

resize(x):替换字符串长度为x

二、经典力扣题目

2.1 反转字符串 344

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

示例 1:

输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]

class Solution {
public:
    void reverseString(vector<char>& s) {
        int SizeNum = s.size();
        for(int i=0,j=SizeNum-1;i<SizeNum/2;i++,j--){
            swap(s[i],s[j]);
        }

    }
};

题解:

翻转字符串,其实就等于将所有元素的位置互换,即使是奇数,最中间的是不会被影响的存在。

用到了库函数swap,实现O(1)空间复杂度

库函数swap:可以从位置上交换两个元素

2.2 反转字符串II  541

2.2.1 题目和题解

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
 

示例 1:

输入:s = "abcdefg", k = 2
输出:"bacdfeg"

class Solution {
public:
    string reverseStr(string s, int k) {
        for(int i=0;i<s.size();i+=(2*k)){
            //注意2*k
            if(i+k <= s.size()){
                //因为在当前状态下,i还没有等于i+2k
                reverse(s.begin()+i,s.begin()+i+k);
                continue;
            }
            
            //说明剩余的字符少于k
            reverse(s.begin()+i,s.end());
        }
        return s;
        
    }
};

题解:

reverse()会将区间[beg,end)内的元素全部逆序;--记住是左闭右开!

在这个示例中,str.begin() + 1表示字符串中的第二个字符的迭代器。str.end()表示字符串末尾的迭代器,reverse()函数将范围从第二个字符开始到末尾的字符进行反转

2.2.2 reverse函数用法

reverse(str.begin(),str.end()) 反转字符串

请注意,reverse()函数会修改原始字符串,使得指定范围内的字符反转

在C++中,reverse()是一个算法函数,用于反转指定范围内的元素顺序

2.2.3 迭代器

在C++中,str.begin()返回一个迭代器,指向std::string容器的第一个字符

迭代器:是一种对象,类似于指针,可以用于遍历容器中的元素。

举例:

auto it = str.begin(); // 获取指向第一个字符的迭代器

char first_char = *it; // 通过解引用操作符获取迭代器it指向的元素

(还有2*k注意一下,容易敲着敲着忘了加乘号)

2.3 反转字符串中的单词 151

给你一个字符串 s ,请你反转字符串中 单词 的顺序。

单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。

返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。

注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

示例 1:

输入:s = "the sky is blue"
输出:"blue is sky the"
class Solution {
public:
    string reverseWords(string s) {
        //此题是在原来字符串上进行修改,空间复杂度为O(1)
        int fast=0;
        int slow=0;
        reverse(s.begin(),s.end());
        //去除空格--规整化
        for(;fast<s.size();fast++){
            if(s[fast]!=' '){
                if(slow!=0){
                    //第一个元素一定不能为空格
                    //之后每个单词后加一个空格
                    s[slow++]=' ';
                }
                
                //遍历完一整个单词
                while(fast<s.size()&&s[fast] != ' '){
                    s[slow]=s[fast];
                    //同时移动同时赋值
                    fast++;
                    slow++;
                }
            }
        }
        s.resize(slow);
        

        //翻转内部单词
        for(fast=0,slow=0;fast<=s.size();++fast){
            if(fast == s.size() ||s[fast] == ' '){
                //reverse是左闭右开!!大部分的库函数都是这样
                reverse(s.begin()+slow,s.begin()+fast);
                slow = fast+1;//成为下个单词的开头
            }

        }

        return s;
    }
};

题解:

思路是,先用双指针,把多余的空格全部去除(先去除所有空格,然后自己添加空格在每个单词后),标准化字符串。然后再逆序字符串,之后再对每一个单词单独逆序,最后输出输入的字符串。空间复杂度O(1) 。

注:这道题做了一段时间,一直没有反转成功,后来检查了半天才发现,reverse是左闭右开的,就是说fast对应的是空格的时候,s.begin()+fast-1其实对应的正好是单词最后一个字符,但是reverse中不需要再-1了,因为开区间。还有一个没有发现bug的原因,是测试用例一开始都是3、5长度的单词,呃这其实不容易发现上面那个问题的!

resize 函数 是一个替换字符串长度的函数

2.4 重复的子字符串 459

给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。

示例 1:

输入: s = "abab"
输出: true
解释: 可由子串 "ab" 重复两次构成

class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        //拼接字符串,可重复构成的前提是,必有字符串处处相等 abab满足--ababababab,从b开始查
        string ss = s+s;
        if(ss.find(s,1) != s.size()){
            //如果从第一个字符开始查找,返回找到的字符串的第一个真子集的索引
            //如果索引恰好等于长度,说明在自身查找了一遍都没有可以和后面连起来的
            return true;
        }else{
            return false;
        }
    }
};

题解:

如果内部是有子字符串组成的,那么把本身和本身连起来,中间一定存在可以联系起来的字符串,它们可以组成字符串,这题使用的就是这个思想

连接字符串 +

寻找字符串并且返回找到第一个真子集字符串的索引 s.find(str,0)--默认从第0个开始寻找

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花火の云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值