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

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

目录

前言

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、付费专栏及课程。

余额充值